Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita7ed9a7

Browse files
authored
Ajax: Support binary data (including FormData)
Two changes have been applied:* prefilters are now applied before data is converted to a string; this allows prefilters to disable such a conversion* a prefilter for binary data is added; it disables data conversion for non-string non-plain-object `data`; for `FormData` bodies, it removes manually-set `Content-Type` header - this is required as browsers need to append their own boundary to the headerRefgh-4150Closesgh-5197
1 parent0b9c503 commita7ed9a7

File tree

8 files changed

+109
-5
lines changed

8 files changed

+109
-5
lines changed

‎package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"karma-qunit":"4.1.2",
5656
"karma-webkit-launcher":"2.1.0",
5757
"load-grunt-tasks":"5.1.0",
58+
"multiparty":"4.2.3",
5859
"native-promise-only":"0.8.1",
5960
"playwright-webkit":"1.29.2",
6061
"promises-aplus-tests":"2.1.2",

‎src/ajax.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,14 +562,14 @@ jQuery.extend( {
562562
}
563563
}
564564

565+
// Apply prefilters
566+
inspectPrefiltersOrTransports(prefilters,s,options,jqXHR);
567+
565568
// Convert data if not already a string
566569
if(s.data&&s.processData&&typeofs.data!=="string"){
567570
s.data=jQuery.param(s.data,s.traditional);
568571
}
569572

570-
// Apply prefilters
571-
inspectPrefiltersOrTransports(prefilters,s,options,jqXHR);
572-
573573
// If request was aborted inside a prefilter, stop there
574574
if(completed){
575575
returnjqXHR;

‎src/ajax/binary.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
importjQueryfrom"../core.js";
2+
3+
import"../ajax.js";
4+
5+
jQuery.ajaxPrefilter(function(s){
6+
7+
// Binary data needs to be passed to XHR as-is without stringification.
8+
if(typeofs.data!=="string"&&!jQuery.isPlainObject(s.data)){
9+
s.processData=false;
10+
}
11+
12+
// `Content-Type` for requests with `FormData` bodies needs to be set
13+
// by the browser as it needs to append the `boundary` it generated.
14+
if(s.datainstanceofwindow.FormData){
15+
s.contentType=false;
16+
}
17+
});

‎src/jquery.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import "./ajax.js";
2323
import"./ajax/xhr.js";
2424
import"./ajax/script.js";
2525
import"./ajax/jsonp.js";
26+
import"./ajax/binary.js";
2627
import"./ajax/load.js";
2728
import"./core/parseXML.js";
2829
import"./core/parseHTML.js";

‎test/data/mock.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ protected function xmlOverJsonp( $req ) {
124124
echo"$cleanCallback($text)\n";
125125
}
126126

127+
protectedfunctionformData($req ) {
128+
$prefix ='multipart/form-data; boundary=--';
129+
$contentTypeValue =$req->headers['CONTENT-TYPE' ];
130+
if (substr($contentTypeValue,0,strlen($prefix ) ) ===$prefix ) {
131+
echo'key1 ->' .$_POST['key1' ] .', key2 ->' .$_POST['key2' ];
132+
}else {
133+
echo'Incorrect Content-Type:' .$contentTypeValue .
134+
"\nExpected prefix:" .$prefix;
135+
}
136+
}
137+
127138
protectedfunctionerror($req ) {
128139
header('HTTP/1.0 400 Bad Request' );
129140
if (isset($req->query['json'] ) ) {

‎test/data/testinit.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,11 @@ function url( value ) {
174174
}
175175

176176
// Ajax testing helper
177-
this.ajaxTest=function(title,expect,options){
178-
QUnit.test(title,function(assert){
177+
this.ajaxTest=function(title,expect,options,wrapper){
178+
if(!wrapper){
179+
wrapper=QUnit.test;
180+
}
181+
wrapper.call(QUnit,title,function(assert){
179182
assert.expect(expect);
180183
varrequestOptions;
181184

‎test/middleware-mockserver.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
consturl=require("url");
44
constfs=require("fs");
55
constgetRawBody=require("raw-body");
6+
constmultiparty=require("multiparty");
67

78
letcspLog="";
89

@@ -141,6 +142,19 @@ const mocks = {
141142
resp.writeHead(200);
142143
resp.end(`${cleanCallback(callback)}(${JSON.stringify(body)})\n`);
143144
},
145+
formData:function(req,resp,next){
146+
constprefix="multipart/form-data; boundary=--";
147+
constcontentTypeValue=req.headers["content-type"];
148+
resp.writeHead(200);
149+
if((prefix||"").startsWith(prefix)){
150+
getMultiPartContent(req).then(function({ fields={}}){
151+
resp.end(`key1 ->${fields.key1}, key2 ->${fields.key2}`);
152+
},next);
153+
}else{
154+
resp.end(`Incorrect Content-Type:${contentTypeValue
155+
}\nExpected prefix:${prefix}`);
156+
}
157+
},
144158
error:function(req,resp){
145159
if(req.query.json){
146160
resp.writeHead(400,{"content-type":"application/json"});
@@ -363,4 +377,18 @@ function getBody( req ) {
363377
});
364378
}
365379

380+
functiongetMultiPartContent(req){
381+
returnnewPromise(function(resolve){
382+
if(req.method!=="POST"){
383+
resolve("");
384+
return;
385+
}
386+
387+
constform=newmultiparty.Form();
388+
form.parse(req,function(_err,fields,files){
389+
resolve({ fields, files});
390+
});
391+
});
392+
}
393+
366394
module.exports=MockserverMiddlewareFactory;

‎test/unit/ajax.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,4 +3105,47 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
31053105
assert.ok(jQuery.active===0,"ajax active counter should be zero: "+jQuery.active);
31063106
});
31073107

3108+
ajaxTest("jQuery.ajax() - FormData",1,function(assert){
3109+
varformData=newFormData();
3110+
formData.append("key1","value1");
3111+
formData.append("key2","value2");
3112+
3113+
return{
3114+
url:url("mock.php?action=formData"),
3115+
method:"post",
3116+
data:formData,
3117+
success:function(data){
3118+
assert.strictEqual(data,"key1 -> value1, key2 -> value2",
3119+
"FormData sent correctly");
3120+
}
3121+
};
3122+
});
3123+
3124+
ajaxTest("jQuery.ajax() - URLSearchParams",1,function(assert){
3125+
varurlSearchParams=newURLSearchParams();
3126+
urlSearchParams.append("name","peter");
3127+
3128+
return{
3129+
url:url("mock.php?action=name"),
3130+
method:"post",
3131+
data:urlSearchParams,
3132+
success:function(data){
3133+
assert.strictEqual(data,"pan","URLSearchParams sent correctly");
3134+
}
3135+
};
3136+
},QUnit.testUnlessIE);
3137+
3138+
ajaxTest("jQuery.ajax() - Blob",1,function(assert){
3139+
varblob=newBlob(["name=peter"],{type:"text/plain"});
3140+
3141+
return{
3142+
url:url("mock.php?action=name"),
3143+
method:"post",
3144+
data:blob,
3145+
success:function(data){
3146+
assert.strictEqual(data,"pan","Blob sent correctly");
3147+
}
3148+
};
3149+
});
3150+
31083151
})();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp