diff --git a/lib/adapters/xhr.js b/lib/adapters/xhr.js index 9c179bf..5cf5429 100644 --- a/lib/adapters/xhr.js +++ b/lib/adapters/xhr.js @@ -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 @@ -27,18 +28,29 @@ module.exports = function xhrAdapter(resolve, reject, config) { delete requestHeaders['Content-Type']; // Let the browser set it } - // Create the request - var request = new (XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP'); - request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true); + 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 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( @@ -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); @@ -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) ? @@ -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) { diff --git a/package.json b/package.json index 8f464d8..99ad985 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/test/specs/requests.spec.js b/test/specs/requests.spec.js index b436d41..a78918e 100644 --- a/test/specs/requests.spec.js +++ b/test/specs/requests.spec.js @@ -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;