| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | 
							- "use strict";
 
- var window = require("global/window")
 
- var isFunction = require("is-function")
 
- var parseHeaders = require("parse-headers")
 
- var xtend = require("xtend")
 
- module.exports = createXHR
 
- // Allow use of default import syntax in TypeScript
 
- module.exports.default = createXHR;
 
- createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
 
- createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
 
- forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
 
-     createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
 
-         options = initParams(uri, options, callback)
 
-         options.method = method.toUpperCase()
 
-         return _createXHR(options)
 
-     }
 
- })
 
- function forEachArray(array, iterator) {
 
-     for (var i = 0; i < array.length; i++) {
 
-         iterator(array[i])
 
-     }
 
- }
 
- function isEmpty(obj){
 
-     for(var i in obj){
 
-         if(obj.hasOwnProperty(i)) return false
 
-     }
 
-     return true
 
- }
 
- function initParams(uri, options, callback) {
 
-     var params = uri
 
-     if (isFunction(options)) {
 
-         callback = options
 
-         if (typeof uri === "string") {
 
-             params = {uri:uri}
 
-         }
 
-     } else {
 
-         params = xtend(options, {uri: uri})
 
-     }
 
-     params.callback = callback
 
-     return params
 
- }
 
- function createXHR(uri, options, callback) {
 
-     options = initParams(uri, options, callback)
 
-     return _createXHR(options)
 
- }
 
- function _createXHR(options) {
 
-     if(typeof options.callback === "undefined"){
 
-         throw new Error("callback argument missing")
 
-     }
 
-     var called = false
 
-     var callback = function cbOnce(err, response, body){
 
-         if(!called){
 
-             called = true
 
-             options.callback(err, response, body)
 
-         }
 
-     }
 
-     function readystatechange() {
 
-         if (xhr.readyState === 4) {
 
-             setTimeout(loadFunc, 0)
 
-         }
 
-     }
 
-     function getBody() {
 
-         // Chrome with requestType=blob throws errors arround when even testing access to responseText
 
-         var body = undefined
 
-         if (xhr.response) {
 
-             body = xhr.response
 
-         } else {
 
-             body = xhr.responseText || getXml(xhr)
 
-         }
 
-         if (isJson) {
 
-             try {
 
-                 body = JSON.parse(body)
 
-             } catch (e) {}
 
-         }
 
-         return body
 
-     }
 
-     function errorFunc(evt) {
 
-         clearTimeout(timeoutTimer)
 
-         if(!(evt instanceof Error)){
 
-             evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
 
-         }
 
-         evt.statusCode = 0
 
-         return callback(evt, failureResponse)
 
-     }
 
-     // will load the data & process the response in a special response object
 
-     function loadFunc() {
 
-         if (aborted) return
 
-         var status
 
-         clearTimeout(timeoutTimer)
 
-         if(options.useXDR && xhr.status===undefined) {
 
-             //IE8 CORS GET successful response doesn't have a status field, but body is fine
 
-             status = 200
 
-         } else {
 
-             status = (xhr.status === 1223 ? 204 : xhr.status)
 
-         }
 
-         var response = failureResponse
 
-         var err = null
 
-         if (status !== 0){
 
-             response = {
 
-                 body: getBody(),
 
-                 statusCode: status,
 
-                 method: method,
 
-                 headers: {},
 
-                 url: uri,
 
-                 rawRequest: xhr
 
-             }
 
-             if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
 
-                 response.headers = parseHeaders(xhr.getAllResponseHeaders())
 
-             }
 
-         } else {
 
-             err = new Error("Internal XMLHttpRequest Error")
 
-         }
 
-         return callback(err, response, response.body)
 
-     }
 
-     var xhr = options.xhr || null
 
-     if (!xhr) {
 
-         if (options.cors || options.useXDR) {
 
-             xhr = new createXHR.XDomainRequest()
 
-         }else{
 
-             xhr = new createXHR.XMLHttpRequest()
 
-         }
 
-     }
 
-     var key
 
-     var aborted
 
-     var uri = xhr.url = options.uri || options.url
 
-     var method = xhr.method = options.method || "GET"
 
-     var body = options.body || options.data
 
-     var headers = xhr.headers = options.headers || {}
 
-     var sync = !!options.sync
 
-     var isJson = false
 
-     var timeoutTimer
 
-     var failureResponse = {
 
-         body: undefined,
 
-         headers: {},
 
-         statusCode: 0,
 
-         method: method,
 
-         url: uri,
 
-         rawRequest: xhr
 
-     }
 
-     if ("json" in options && options.json !== false) {
 
-         isJson = true
 
-         headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
 
-         if (method !== "GET" && method !== "HEAD") {
 
-             headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
 
-             body = JSON.stringify(options.json === true ? body : options.json)
 
-         }
 
-     }
 
-     xhr.onreadystatechange = readystatechange
 
-     xhr.onload = loadFunc
 
-     xhr.onerror = errorFunc
 
-     // IE9 must have onprogress be set to a unique function.
 
-     xhr.onprogress = function () {
 
-         // IE must die
 
-     }
 
-     xhr.onabort = function(){
 
-         aborted = true;
 
-     }
 
-     xhr.ontimeout = errorFunc
 
-     xhr.open(method, uri, !sync, options.username, options.password)
 
-     //has to be after open
 
-     if(!sync) {
 
-         xhr.withCredentials = !!options.withCredentials
 
-     }
 
-     // Cannot set timeout with sync request
 
-     // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
 
-     // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
 
-     if (!sync && options.timeout > 0 ) {
 
-         timeoutTimer = setTimeout(function(){
 
-             if (aborted) return
 
-             aborted = true//IE9 may still call readystatechange
 
-             xhr.abort("timeout")
 
-             var e = new Error("XMLHttpRequest timeout")
 
-             e.code = "ETIMEDOUT"
 
-             errorFunc(e)
 
-         }, options.timeout )
 
-     }
 
-     if (xhr.setRequestHeader) {
 
-         for(key in headers){
 
-             if(headers.hasOwnProperty(key)){
 
-                 xhr.setRequestHeader(key, headers[key])
 
-             }
 
-         }
 
-     } else if (options.headers && !isEmpty(options.headers)) {
 
-         throw new Error("Headers cannot be set on an XDomainRequest object")
 
-     }
 
-     if ("responseType" in options) {
 
-         xhr.responseType = options.responseType
 
-     }
 
-     if ("beforeSend" in options &&
 
-         typeof options.beforeSend === "function"
 
-     ) {
 
-         options.beforeSend(xhr)
 
-     }
 
-     // Microsoft Edge browser sends "undefined" when send is called with undefined value.
 
-     // XMLHttpRequest spec says to pass null as body to indicate no body
 
-     // See https://github.com/naugtur/xhr/issues/100.
 
-     xhr.send(body || null)
 
-     return xhr
 
- }
 
- function getXml(xhr) {
 
-     // xhr.responseXML will throw Exception "InvalidStateError" or "DOMException"
 
-     // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML.
 
-     try {
 
-         if (xhr.responseType === "document") {
 
-             return xhr.responseXML
 
-         }
 
-         var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"
 
-         if (xhr.responseType === "" && !firefoxBugTakenEffect) {
 
-             return xhr.responseXML
 
-         }
 
-     } catch (e) {}
 
-     return null
 
- }
 
- function noop() {}
 
 
  |