Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XDomainRequest support #140

Merged
merged 14 commits into from Nov 21, 2015
47 changes: 29 additions & 18 deletions lib/adapters/xhr.js
Expand Up @@ -7,6 +7,7 @@ var utils = require('./../utils');
var buildURL = require('./../helpers/buildURL');
var parseHeaders = require('./../helpers/parseHeaders');
var transformData = require('./../helpers/transformData');
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');

module.exports = function xhrAdapter(resolve, reject, config) {
// Transform request data
Expand All @@ -27,18 +28,29 @@ module.exports = function xhrAdapter(resolve, reject, config) {
delete requestHeaders['Content-Type']; // Let the browser set it
}

var adapter = (XMLHttpRequest || ActiveXObject);
var loadEvent = 'onreadystatechange';
var xDomain = false;

// For IE 8/9 CORS support
if(!isURLSameOrigin(config.url) && window.XDomainRequest){
adapter = window.XDomainRequest;
loadEvent = 'onload';
xDomain = true;
}

// Create the request
var request = new (XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP');
var request = new adapter('Microsoft.XMLHTTP');
request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);

// Set the request timeout in MS
request.timeout = config.timeout;

// Listen for ready state
request.onreadystatechange = function () {
if (request && request.readyState === 4) {
request[loadEvent] = function () {
if (request && (request.readyState === 4 || xDomain)) {
// Prepare the response
var responseHeaders = parseHeaders(request.getAllResponseHeaders());
var responseHeaders = xDomain ? null : parseHeaders(request.getAllResponseHeaders());
var responseData = ['text', ''].indexOf(config.responseType || '') !== -1 ? request.responseText : request.response;
var response = {
data: transformData(
Expand All @@ -51,9 +63,8 @@ module.exports = function xhrAdapter(resolve, reject, config) {
headers: responseHeaders,
config: config
};

// Resolve or reject the Promise based on the status
(request.status >= 200 && request.status < 300 ?
((request.status >= 200 && request.status < 300) || (request.responseText && xDomain) ?
resolve :
reject)(response);

Expand All @@ -67,7 +78,6 @@ module.exports = function xhrAdapter(resolve, reject, config) {
// Specifically not if we're in a web worker, or react-native.
if (utils.isStandardBrowserEnv()) {
var cookies = require('./../helpers/cookies');
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');

// Add xsrf header
var xsrfValue = isURLSameOrigin(config.url) ?
Expand All @@ -80,16 +90,17 @@ module.exports = function xhrAdapter(resolve, reject, config) {
}

// Add headers to the request
utils.forEach(requestHeaders, function (val, key) {
// Remove Content-Type if data is undefined
if (!data && key.toLowerCase() === 'content-type') {
delete requestHeaders[key];
}
// Otherwise add header to the request
else {
request.setRequestHeader(key, val);
}
});
if(!xDomain)
utils.forEach(requestHeaders, function (val, key) {
// Remove Content-Type if data is undefined
if (!data && key.toLowerCase() === 'content-type') {
delete requestHeaders[key];
}
// Otherwise add header to the request
else {
request.setRequestHeader(key, val);
}
});

// Add withCredentials to request if needed
if (config.withCredentials) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -4,6 +4,7 @@
"description": "Promise based HTTP client for the browser and node.js",
"main": "index.js",
"scripts": {
"build": "./node_modules/.bin/grunt build",
"test": "./node_modules/.bin/grunt test",
"start": "node ./sandbox/server.js",
"examples": "node ./examples/server.js",
Expand Down
35 changes: 35 additions & 0 deletions test/specs/requests.spec.js
Expand Up @@ -54,6 +54,41 @@ describe('requests', function () {
}, 0);
});

it('should make cross domian http request', function (done) {
var request, response;

axios({
method: 'post',
url: 'www.someurl.com/foo',
xDomain: true
}).then(function(res){
response = res;
});

setTimeout(function () {
request = jasmine.Ajax.requests.mostRecent();
request.respondWith({
status: 200,
statusText: 'OK',
responseText: '{"foo": "bar"}',
headers: {
'Content-Type': 'application/json'
}
});

setTimeout(function () {
expect(response.data.foo).toEqual('bar');
expect(response.status).toEqual(200);
expect(response.statusText).toEqual('OK');
expect(response.headers['content-type']).toEqual('application/json');
done();
}, 0);

}, 0);

});


it('should supply correct response', function (done) {
var request, response;

Expand Down