Skip to content

Commit 60f8d78

Browse files
committed
fixed ajax to send simple CORS requests
1 parent 87066d0 commit 60f8d78

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

ajax-test.js

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,39 +109,52 @@ if(typeof XDomainRequest === 'undefined') {
109109
});
110110
});
111111

112-
// Test GET CORS:
113-
QUnit.asyncTest("GET CORS should set content-type header (#187)", function () {
114-
115-
var hasCorrectHeader, restore;
112+
// Test simple GET CORS:
113+
QUnit.asyncTest("GET CORS should be a simple request - without a preflight (#187)", function () {
114+
115+
// CORS simple requests: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests
116+
var isSimpleRequest = true, restore;
117+
var simpleMethods = ['GET', 'POST', 'HEAD'];
118+
var simpleHeaders = [
119+
'Accept','Accept-Language','Content-Language','Content-Type',
120+
'DPR', 'Downlink', 'Save-Data', 'Viewport-Width', 'Width'
121+
];
122+
var simpleContentType = 'application/x-www-form-urlencoded';
123+
116124
restore = makeFixture(function () {
117125
this.open = function (type, url) {
126+
if (simpleMethods.indexOf(type) === -1){
127+
isSimpleRequest = false;
128+
}
118129
};
119130

131+
var response = {};
120132
this.send = function () {
133+
this.responseText = JSON.stringify(response);
121134
this.readyState = 4;
122135
this.status = 200;
123136
this.onreadystatechange();
124137
};
125-
138+
126139
this.setRequestHeader = function (header, value) {
127-
if (header === "Content-Type" && value === "application/x-www-form-urlencoded"){
128-
hasCorrectHeader = true;
140+
if (header === "Content-Type" && value !== simpleContentType){
141+
isSimpleRequest = false;
142+
}
143+
if (simpleHeaders.indexOf(header) === -1){
144+
isSimpleRequest = false;
129145
}
130-
var o = {};
131-
o[header] = value;
132-
this.responseText = JSON.stringify(o);
146+
response[header] = value;
133147
};
134148
});
135149

136150
ajax({
137151
url: "http://query.yahooapis.com/v1/public/yql",
138152
data: {
139-
fmt: "JSON",
140153
q: 'select * from geo.places where text="sunnyvale, ca"',
141154
format: "json"
142155
}
143156
}).then(function(response){
144-
QUnit.ok(hasCorrectHeader, "Content-Type for GET CORS should be set to `application/x-www-form-urlencoded`");
157+
QUnit.ok(isSimpleRequest, "CORS GET is simple");
145158
restore();
146159
start();
147160
}, function(err){

ajax.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,17 +159,24 @@ module.exports = namespace.ajax = function (o) {
159159
}
160160
xhr.open(type, url);
161161

162-
var isJson = o.dataType.indexOf("json") >= 0;
162+
// For CORS to send a "simple" request (to avoid a preflight check), the following methods are allowed: GET/POST/HEAD,
163+
// see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests
164+
var isSimpleCors = o.crossDomain && ['GET', 'POST', 'HEAD'].indexOf(type) !== -1;
165+
163166
if (isPost) {
164-
data = (isJson && !o.crossDomain) ?
167+
var isJson = o.dataType.indexOf("json") >= 0;
168+
data = (isJson && !isSimpleCors) ?
165169
(typeof o.data === "object" ? JSON.stringify(o.data) : o.data):
166170
$._formData(o.data);
167-
xhr.setRequestHeader("Content-Type", (isJson && !o.crossDomain) ? "application/json" : "application/x-www-form-urlencoded");
168-
} else if (type === "GET" && o.crossDomain){
169-
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
171+
172+
// CORS simple: `Content-Type` has to be `application/x-www-form-urlencoded`:
173+
xhr.setRequestHeader("Content-Type", (isJson && !isSimpleCors) ? "application/json" : "application/x-www-form-urlencoded");
174+
}
175+
176+
// CORS simple: no custom headers, so we don't add `X-Requested-With` header:
177+
if (!isSimpleCors){
178+
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest" );
170179
}
171-
// X-Requested-With header
172-
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest" );
173180

174181
xhr.send(data);
175182
return promise;

0 commit comments

Comments
 (0)