| 'use strict'; |
| |
| var createBlob = require('./blob.js'); |
| var utils = require('../utils'); |
| |
| module.exports = function(options, callback) { |
| |
| var xhr, timer, hasUpload; |
| |
| var abortReq = function () { |
| xhr.abort(); |
| }; |
| |
| if (options.xhr) { |
| xhr = new options.xhr(); |
| } else { |
| xhr = new XMLHttpRequest(); |
| } |
| |
| // cache-buster, specifically designed to work around IE's aggressive caching |
| // see http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/ |
| if (options.method === 'GET' && !options.cache) { |
| var hasArgs = options.url.indexOf('?') !== -1; |
| options.url += (hasArgs ? '&' : '?') + '_nonce=' + Date.now(); |
| } |
| |
| xhr.open(options.method, options.url); |
| xhr.withCredentials = true; |
| |
| if (options.json) { |
| options.headers.Accept = 'application/json'; |
| options.headers['Content-Type'] = options.headers['Content-Type'] || |
| 'application/json'; |
| if (options.body && |
| options.processData && |
| typeof options.body !== "string") { |
| options.body = JSON.stringify(options.body); |
| } |
| } |
| |
| if (options.binary) { |
| xhr.responseType = 'arraybuffer'; |
| } |
| |
| if (!('body' in options)) { |
| options.body = null; |
| } |
| |
| for (var key in options.headers) { |
| if (options.headers.hasOwnProperty(key)) { |
| xhr.setRequestHeader(key, options.headers[key]); |
| } |
| } |
| |
| if (options.timeout > 0) { |
| timer = setTimeout(abortReq, options.timeout); |
| xhr.onprogress = function () { |
| clearTimeout(timer); |
| timer = setTimeout(abortReq, options.timeout); |
| }; |
| if (typeof hasUpload === 'undefined') { |
| // IE throws an error if you try to access it directly |
| hasUpload = Object.keys(xhr).indexOf('upload') !== -1; |
| } |
| if (hasUpload) { // does not exist in ie9 |
| xhr.upload.onprogress = xhr.onprogress; |
| } |
| } |
| |
| xhr.onreadystatechange = function () { |
| if (xhr.readyState !== 4) { |
| return; |
| } |
| |
| var response = { |
| statusCode: xhr.status |
| }; |
| |
| if (xhr.status >= 200 && xhr.status < 300) { |
| var data; |
| if (options.binary) { |
| data = createBlob([xhr.response || ''], { |
| type: xhr.getResponseHeader('Content-Type') |
| }); |
| } else { |
| data = xhr.responseText; |
| } |
| callback(null, response, data); |
| } else { |
| var err = {}; |
| try { |
| err = JSON.parse(xhr.response); |
| } catch(e) {} |
| callback(err, response); |
| } |
| }; |
| |
| if (options.body && (options.body instanceof Blob)) { |
| utils.readAsBinaryString(options.body, function (binary) { |
| xhr.send(utils.fixBinary(binary)); |
| }); |
| } else { |
| xhr.send(options.body); |
| } |
| |
| return {abort: abortReq}; |
| }; |