Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

xhr

Package Overview
Dependencies
Maintainers
2
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xhr - npm Package Compare versions

Comparing version 1.17.0 to 2.0.0

183

index.js

@@ -0,10 +1,6 @@

"use strict";
var window = require("global/window")
var once = require("once")
var parseHeaders = require('parse-headers')
var parseHeaders = require("parse-headers")
var messages = {
"0": "Internal XMLHttpRequest Error",
"4": "4xx Client Error",
"5": "5xx Server Error"
}

@@ -17,2 +13,72 @@ var XHR = window.XMLHttpRequest || noop

function createXHR(options, callback) {
function readystatechange() {
if (xhr.readyState === 4) {
loadFunc()
}
}
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 if (xhr.responseType === "text" || !xhr.responseType) {
body = xhr.responseText || xhr.responseXML
}
if (isJson) {
try {
body = JSON.parse(body)
} catch (e) {}
}
return body
}
var failureResponse = {
body: undefined,
headers: {},
statusCode: 0,
method: method,
url: uri,
rawRequest: xhr
}
function errorFunc(evt) {
clearTimeout(timeoutTimer)
if(! evt instanceof Error){
evt = new Error(""+evt)
}
evt.statusCode = 0
callback(evt, failureResponse)
}
// will load the data & process the response in a special response object
function loadFunc() {
clearTimeout(timeoutTimer)
var 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")
}
callback(err, response, response.body)
}
if (typeof options === "string") {

@@ -35,2 +101,3 @@ options = { uri: options }

var key
var uri = xhr.url = options.uri || options.url

@@ -42,8 +109,7 @@ var method = xhr.method = options.method || "GET"

var isJson = false
var key
var load = options.response ? loadResponse : loadXhr
var timeoutTimer
if ("json" in options) {
isJson = true
headers["Accept"] = "application/json"
headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
if (method !== "GET" && method !== "HEAD") {

@@ -56,4 +122,4 @@ headers["Content-Type"] = "application/json"

xhr.onreadystatechange = readystatechange
xhr.onload = load
xhr.onerror = error
xhr.onload = loadFunc
xhr.onerror = errorFunc
// IE9 must have onprogress be set to a unique function.

@@ -63,13 +129,14 @@ xhr.onprogress = function () {

}
// hate IE
xhr.ontimeout = noop
xhr.ontimeout = errorFunc
xhr.open(method, uri, !sync)
//backward compatibility
if (options.withCredentials || (options.cors && options.withCredentials !== false)) {
xhr.withCredentials = true
}
//has to be after open
xhr.withCredentials = !!options.withCredentials
// Cannot set timeout with sync request
if (!sync) {
xhr.timeout = "timeout" in options ? options.timeout : 5000
// 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(){
xhr.abort("timeout");
}, options.timeout+2 );
}

@@ -101,79 +168,3 @@

function readystatechange() {
if (xhr.readyState === 4) {
load()
}
}
function getBody() {
// Chrome with requestType=blob throws errors arround when even testing access to responseText
var body = null
if (xhr.response) {
body = xhr.response
} else if (xhr.responseType === 'text' || !xhr.responseType) {
body = xhr.responseText || xhr.responseXML
}
if (isJson) {
try {
body = JSON.parse(body)
} catch (e) {}
}
return body
}
function getStatusCode() {
return xhr.status === 1223 ? 204 : xhr.status
}
// if we're getting a none-ok statusCode, build & return an error
function errorFromStatusCode(status) {
var error = null
if (status === 0 || (status >= 400 && status < 600)) {
var message = (typeof body === "string" ? body : false) ||
messages[String(status).charAt(0)]
error = new Error(message)
error.statusCode = status
}
return error
}
// will load the data & process the response in a special response object
function loadResponse() {
var status = getStatusCode()
var error = errorFromStatusCode(status)
var response = {
body: getBody(),
statusCode: status,
statusText: xhr.statusText,
raw: xhr
}
if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
response.headers = parseHeaders(xhr.getAllResponseHeaders())
} else {
response.headers = {}
}
callback(error, response, response.body)
}
// will load the data and add some response properties to the source xhr
// and then respond with that
function loadXhr() {
var status = getStatusCode()
var error = errorFromStatusCode(status)
xhr.status = xhr.statusCode = status
xhr.body = getBody()
xhr.headers = parseHeaders(xhr.getAllResponseHeaders())
callback(error, xhr, xhr.body)
}
function error(evt) {
callback(evt, xhr)
}
}

@@ -180,0 +171,0 @@

{
"name": "xhr",
"version": "1.17.0",
"version": "2.0.0",
"description": "small xhr abstraction",

@@ -45,19 +45,3 @@ "keywords": [

"browser": "run-browser test/index.js"
},
"testling": {
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"firefox/17..latest",
"firefox/nightly",
"chrome/22..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
}
}

@@ -5,3 +5,3 @@ # xhr

[![browser support](https://ci.testling.com/raynos/xhr.png)](https://ci.testling.com/Raynos/xhr)
Browser support: IE8+ and everything else.

@@ -20,4 +20,3 @@ ## Example

}, function (err, resp, body) {
// resp === xhr
// check resp.body or resp.statusCode
// check resp.statusCode
})

@@ -39,4 +38,3 @@ ```

json: Object?,
withCredentials: Boolean?,
response: Boolean?
withCredentials: Boolean?
}

@@ -50,10 +48,24 @@ xhr := (XhrOptions, Callback<Response>) => Request

Your callback will be called once with the arguments
( [`Error`][5], `response` , `body` ) where the response is depending on
`options.response` and body will be either
[`xhr.response`][6], [`xhr.responseText`][7] or
( [`Error`][5], `response` , `body` ) where the response is an object:
```js
{
body: Object||String,
statusCode: Number,
method: String,
headers: {},
url: String,
rawRequest: xhr
}
```
- `body`: HTTP response body - [`xhr.response`][6], [`xhr.responseText`][7] or
[`xhr.responseXML`][8] depending on the request type.
- `rawRequest`: Original [`XMLHttpRequest`][3] instance
or [`XDomainRequest`][4] instance (if on IE8/IE9 &&
`options.useXDR` is set to `true`)
- `headers`: A collection of headers where keys are header names converted to lowercase
Your callback will be called with an [`Error`][5] if the
resulting status of the request is either `0`, `4xx` or `5xx`
Your callback will be called with an [`Error`][5] if there is an error in the browser that prevents sending the request.
A HTTP 500 response is not going to cause an error to be returned.
If `options` is a string then it's a short hand for

@@ -67,8 +79,2 @@ `{ method: "GET", uri: string }`

### `options.response`
Specify the format of the response. Defaults to return the xhr/xdr-object
with body, headers and status-properties added. When set to `true` a special response
object is returned that includes parsed response headers, status and body.
`options.response` must be set to `true` for IE8 support.
### `options.useXDR`

@@ -106,4 +112,3 @@

A numeric timeout to use for this xhr request. Defaults to 5
seconds. Ignored when `options.sync` is true.
Number of miliseconds to wait for response. Defaults to 0 (no timeout). Ignored when `options.sync` is true.

@@ -123,5 +128,2 @@ ### `options.json`

For backward-compatibility defaults to true
when deprecated `options.cors` is also true.
A wildcard `*` cannot be used in the `Access-Control-Allow-Origin` header when `withCredentials` is true.

@@ -128,0 +130,0 @@ The header needs to specify your origin explicitly or browser will abort the request.

@@ -6,6 +6,4 @@ var window = require("global/window")

test("constructs and calls callback without throwing", function(assert) {
xhr({
response: !!window.XDomainRequest //currently, IE8 will fail if this is not set to true, as documented
}, function (err, resp, body) {
test("constructs and calls callback without throwing", function (assert) {
xhr({}, function (err, resp, body) {
assert.ok(true, "got here")

@@ -16,9 +14,15 @@ assert.end()

test("can GET current page", function(assert) {
test("can GET a url", function (assert) {
xhr({
headers: {accept: "text/html"},
uri: window.location.href,
response: !!window.XDomainRequest
headers: {
accept: "text/html"
},
uri: "http://reqr.es/api/stuff"
}, function (err, resp, body) {
assert.ifError(err, "no err")
assert.equal(resp.statusCode, 200)
assert.equal(typeof resp.rawRequest, "object")
assert.equal(resp.headers['content-type'].indexOf('application/json'), 0)
assert.notEqual(resp.body.length, 0)
assert.notEqual(body.length, 0)
assert.end()

@@ -28,14 +32,12 @@ })

test("can GET current page with response option = true", function(assert) {
test("Returns http error responses like npm's request", function (assert) {
xhr({
headers: {accept: "text/html"},
uri: window.location.href,
response: true
headers: {
accept: "text/html"
},
uri: "http://reqr.es/api/stuff/23"
}, function (err, resp, body) {
assert.ifError(err, "no err")
assert.equal(resp.statusCode, 200)
assert.equal(resp.statusText, 'OK')
assert.equal(resp.headers['content-type'].indexOf('text/html'), 0) //can be 'text/html; charset=UTF-8' in IE8 particularly
assert.notEqual(resp.body.length, 0)
assert.notEqual(body.length, 0)
assert.equal(resp.statusCode, 404)
assert.equal(typeof resp.rawRequest, "object")
assert.end()

@@ -45,24 +47,30 @@ })

test("withCredentials option", function(assert) {
if(!window.XDomainRequest){
test("Times out to an error ", function (assert) {
xhr({
headers: {
accept: "text/html"
},
timeout: 1000,
uri: "http://reqr.es/api/stuff?delay=10"
}, function (err, resp, body) {
assert.ok(err instanceof Error, "should return error")
assert.equal(resp.statusCode, 0)
assert.end()
})
})
test("withCredentials option", function (assert) {
if (!window.XDomainRequest) {
var req = xhr({}, function () {})
assert.ok(
!req.withCredentials,
"withCredentials not true when nothing set in options"
assert.ok(!req.withCredentials,
"withCredentials not true"
)
req = xhr({
cors: true
withCredentials: true
}, function () {})
assert.ok(
req.withCredentials,
"withCredentials set to true when cors is true in options"
"withCredentials set to true"
)
req = xhr({
cors: true,
withCredentials: false
}, function () {})
assert.ok(
!req.withCredentials,
"withCredentials set to false when set to false in options"
)
} else {

@@ -77,34 +85,25 @@ assert.ok(

test("XDR usage (run on IE8 or 9)", function(assert) {
test("XDR usage (run on IE8 or 9)", function (assert) {
var req = xhr({
useXDR: true,
response:true,
uri: window.location.href,
}, function () {})
assert.ok(
!window.XDomainRequest || window.XDomainRequest === req.constructor,
assert.ok(!window.XDomainRequest || window.XDomainRequest === req.constructor,
"Uses XDR when told to"
)
req = xhr({
cors: true,
uri: window.location.href,
}, function () {})
assert.ok(
!window.XDomainRequest || window.XDomainRequest === req.constructor,
"Uses XDR with deprecated option cors"
)
if(!!window.XDomainRequest){
assert.throws(function(){
if (!!window.XDomainRequest) {
assert.throws(function () {
xhr({
useXDR: true,
uri: window.location.href,
headers:{"foo":"bar"}
headers: {
"foo": "bar"
}
}, function () {})
},true,"Throws when trying to send headers with XDR")
}, true, "Throws when trying to send headers with XDR")
}
assert.end()
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc