Gathering detailed insights and metrics for @videojs/xhr
Gathering detailed insights and metrics for @videojs/xhr
Gathering detailed insights and metrics for @videojs/xhr
Gathering detailed insights and metrics for @videojs/xhr
npm install @videojs/xhr
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
1 Stars
300 Commits
3 Forks
2 Watching
22 Branches
11 Contributors
Updated on 06 Jun 2024
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
-5.8%
75,401
Compared to previous day
Last week
4.6%
417,160
Compared to previous week
Last month
8.1%
1,752,247
Compared to previous month
Last year
-13.6%
17,574,534
Compared to previous year
Originally forked from naugtur/xhr.
A small XMLHttpRequest wrapper. Designed for use with browserify, webpack etc.
API is a subset of request so you can write code that works in both node.js and the browser by using require('request')
in your code and telling your browser bundler to load xhr
instead of request
.
For browserify, add a browser field to your package.json
:
"browser": {
"request": "@videojs/xhr"
}
For webpack, add a resolve.alias field to your configuration:
"resolve": {
"alias": {
"request$": "@videojs/xhr"
}
}
Browser support: IE8+ and everything else.
npm install @videojs/xhr
1var xhr = require("@videojs/xhr") 2 3xhr({ 4 method: "post", 5 body: someJSONString, 6 uri: "/foo", 7 headers: { 8 "Content-Type": "application/json" 9 } 10}, function (err, resp, body) { 11 // check resp.statusCode 12})
var req = xhr(options, callback)
1type XhrOptions = String | { 2 useXDR: Boolean?, 3 sync: Boolean?, 4 uri: String, 5 url: String, 6 method: String?, 7 timeout: Number?, 8 headers: Object?, 9 body: String? | Object?, 10 json: Boolean? | Object?, 11 username: String?, 12 password: String?, 13 withCredentials: Boolean?, 14 responseType: String?, 15 beforeSend: Function? 16} 17xhr := (XhrOptions, Callback<Response>) => Request
the returned object is either an XMLHttpRequest
instance
or an XDomainRequest
instance (if on IE8/IE9 &&
options.useXDR
is set to true
)
Your callback will be called once with the arguments
( Error
, response
, body
) where the response is an object:
1{ 2 body: Object||String, 3 statusCode: Number, 4 method: String, 5 headers: {}, 6 url: String, 7 rawRequest: xhr 8}
body
: HTTP response body - XMLHttpRequest.response
, XMLHttpRequest.responseText
or
XMLHttpRequest.responseXML
depending on the request type.rawRequest
: Original XMLHttpRequest
instance
or XDomainRequest
instance (if on IE8/IE9 &&
options.useXDR
is set to true
)headers
: A collection of headers where keys are header names converted to lowercaseYour callback will be called with an Error
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.
var req = xhr(url, callback)
-
a simple string instead of the options. In this case, a GET request will be made to that url.
var req = xhr(url, options, callback)
-
the above may also be called with the standard set of options.
var req = xhr.{post, put, patch, del, head, get}(url, callback)
var req = xhr.{post, put, patch, del, head, get}(options, callback)
var req = xhr.{post, put, patch, del, head, get}(url, options, callback)
The xhr
module has convience functions attached that will make requests with the given method.
Each function is named after its method, with the exception of DELETE
which is called xhr.del
for compatibility.
The method shorthands may be combined with the url-first form of xhr
for succinct and descriptive requests. For example,
1xhr.post('/post-to-me', function(err, resp) { 2 console.log(resp.body) 3})
or
1xhr.del('/delete-me', { headers: { my: 'auth' } }, function (err, resp) { 2 console.log(resp.statusCode); 3})
options.method
Specify the method the XMLHttpRequest
should be opened
with. Passed to XMLHttpRequest.open
. Defaults to "GET"
options.useXDR
Specify whether this is a cross origin (CORS) request for IE<10.
Switches IE to use XDomainRequest
instead of XMLHttpRequest
.
Ignored in other browsers.
Note that headers cannot be set on an XDomainRequest instance.
options.sync
Specify whether this is a synchrounous request. Note that when this is true the callback will be called synchronously. In most cases this option should not be used. Only use if you know what you are doing!
options.body
Pass in body to be send across the XMLHttpRequest
.
Generally should be a string. But anything that's valid as
a parameter to XMLHttpRequest.send
should work (Buffer for file, etc.).
If options.json
is true
, then this must be a JSON-serializable object. options.body
is passed to JSON.stringify
and sent.
options.uri
or options.url
The uri to send a request to. Passed to XMLHttpRequest.open
. options.url
and options.uri
are aliases for each other.
options.headers
An object of headers that should be set on the request. The
key, value pair is passed to XMLHttpRequest.setRequestHeader
options.timeout
Number of miliseconds to wait for response. Defaults to 0 (no timeout). Ignored when options.sync
is true.
options.json
Set to true
to send request as application/json
(see options.body
) and parse response from JSON.
For backwards compatibility options.json
can also be a valid JSON-serializable value to be sent to the server. Additionally the response body is still parsed as JSON
For sending booleans as JSON body see FAQ
options.withCredentials
Specify whether user credentials are to be included in a cross-origin
request. Sets XMLHttpRequest.withCredentials
. Defaults to false.
A wildcard *
cannot be used in the Access-Control-Allow-Origin
header when withCredentials
is true.
The header needs to specify your origin explicitly or browser will abort the request.
options.responseType
Determines the data type of the response
. Sets XMLHttpRequest.responseType
. For example, a responseType
of document
will return a parsed Document
object as the response.body
for an XML resource.
options.beforeSend
A function being called right before the send
method of the XMLHttpRequest
or XDomainRequest
instance is called. The XMLHttpRequest
or XDomainRequest
instance is passed as an argument.
options.xhr
Pass an XMLHttpRequest
object (or something that acts like one) to use instead of constructing a new one using the XMLHttpRequest
or XDomainRequest
constructors. Useful for testing.
This module exposes the following helpers on the xhr
object.
xhr.httpHandler(callback, decodeResponseBody) => XhrCallback
httpHandler
is a wrapper for the [XhrCallback][] which returns an error for HTTP Status Codes 4xx and 5xx. Given a callback, it'll either return an error with the response body as the error's cause, or return the response body.
Usage like so:
1xhr({
2 uri: "https://example.com/foo",
3 responseType: 'arraybuffer'
4}, xhr.httpHandler(function(err, responseBody) {
5
6 // we got an error if the XHR errored out or if the status code was 4xx/5xx
7 if (err) {
8 // error cause is coming soon to JavaScript https://github.com/tc39/proposal-error-cause
9 throw new Error(err, {cause: err.cause});
10 }
11
12 // this will log an ArrayBuffer
13 console.log(responseBody);
14});
1xhr({
2 uri: "https://example.com/foo",
3 responseType: 'arraybuffer'
4}, xhr.httpHandler(function(err, responseBody) {
5
6 if (err) {
7 throw new Error(err, {cause: err.cause});
8 }
9
10 // in this case, responseBody will be a String
11 console.log(responseBody);
12},
13
14// passing true as the second argument will cause httpHandler try and decode the response body into a string
15true)
xhr.requestInterceptorsStorage
and xhr.responseInterceptorsStorage
have the following API:
1export interface NetworkRequest { 2 headers: Record<string, string>; 3 uri: string; 4 metadata: Record<string, unknown>; 5 body?: unknown; 6 retry?: Retry; 7 timeout?: number; 8} 9 10export interface NetworkResponse { 11 headers: Record<string, string>; 12 responseUrl: string; 13 body?: unknown; 14 responseType?: XMLHttpRequestResponseType; 15} 16 17export type Interceptor<T> = (payload: T) => T; 18 19export interface InterceptorsStorage<T> { 20 enable(): void; 21 disable(): void; 22 getIsEnabled(): boolean; 23 reset(): void; 24 addInterceptor(type: string, interceptor: Interceptor<T>): boolean; 25 removeInterceptor(type: string, interceptor: Interceptor<T>): boolean; 26 clearInterceptorsByType(type: string): boolean; 27 clear(): boolean; 28 getForType(type: string): Set<Interceptor<T>>; 29 execute(type: string, payload: T): T; 30} 31
Usage:
1xhr.requestInterceptorsStorage.enable(); 2xhr.responseInterceptorsStorage.enable(); 3 4xhr.requestInterceptorsStorage.addInterceptor('segment', (request) => { 5 // read / update NetworkRequest 6 return request; 7}); 8 9xhr.responseInterceptorsStorage.addInterceptor('segement', (response) => { 10 // read / update NetworkResponse 11 return response; 12}); 13 14xhr({ 15 uri: 'https://host/segment', 16 responseType: 'arraybuffer', 17 requestType: 'segement' 18}, function(err, response, responseBody) { 19 // your callback 20}); 21
xhr.retryManager
has the following API
1export interface Retry { 2 getCurrentDelay(): number; 3 getCurrentMinPossibleDelay(): number; 4 getCurrentMaxPossibleDelay(): number; 5 getCurrentFuzzedDelay(): number; 6 shouldRetry(): boolean; 7 moveToNextAttempt(): void; 8} 9 10export interface RetryOptions { 11 maxAttempts?: number; 12 delayFactor?: number; 13 fuzzFactor?: number; 14 initialDelay?: number; 15} 16 17export interface RetryManager { 18 enable(): void; 19 disable(): void; 20 reset(): void; 21 getMaxAttempts(): number; 22 setMaxAttempts(maxAttempts: number): void; 23 getDelayFactor(): number; 24 setDelayFactor(delayFactor: number): void; 25 getFuzzFactor(): number; 26 setFuzzFactor(fuzzFactor: number): void; 27 getInitialDelay(): number; 28 setInitialDelay(initialDelay: number): void; 29 createRetry(options?: RetryOptions): Retry; 30}
Usage:
1xhr.retryManager.enable(); 2 3xhr.retryManager.setMaxAttempts(2); 4 5xhr({ 6 uri: 'https://host/segment', 7 responseType: 'arraybuffer', 8 retry: xhr.retryManager.createRetry(), 9}, function(err, response, responseBody) { 10 // your callback 11}); 12 13// or override values for specific request: 14xhr({ 15 uri: 'https://host/segment', 16 responseType: 'arraybuffer', 17 retry: xhr.retryManager.createRetry({ maxAttempts: 3 }), 18}, function(err, response, responseBody) { 19 // your callback 20}); 21 22 23// you can combine interceptors/retry APIs if you dont have direct acces to the request: 24xhr.requestInterceptorsStorage.addInterceptor('segment', (request) => { 25 // read / update NetworkRequest 26 request.retry = xhr.retryManager.createRetry(); 27 return request; 28}); 29 30
options.json
- you can set it to true
on a GET request to tell xhr
to parse the response body.options.json
body is returned as-is (a string or when responseType
is set and the browser supports it - a result of parsing JSON or XML)options.body
should be a string. You need to serialize your object before passing to xhr
for sending.options.json:true
with options.body
for convenience - then xhr
will do the serialization and set content-type accordingly..pipe()
etc.
"true"
as body by passing it as options.json
anymore?
true
as a value was a bug. Despite what JSON.stringify
does, the string "true"
is not valid JSON. If you're sending booleans as JSON, please consider wrapping them in an object or array to save yourself from more trouble in the future. To bring back the old behavior, hardcode options.json
to true
and set options.body
to your boolean value.onprogress
listener?
beforeSend
function for non-standard things that are browser specific. In this case:1xhr({ 2 ... 3 beforeSend: function(xhrObject){ 4 xhrObject.onprogress = function(){} 5 } 6})
You can override the constructor used to create new requests for testing. When you're making a new request:
1xhr({ xhr: new MockXMLHttpRequest() })
or you can override the constructors used to create requests at the module level:
1xhr.XMLHttpRequest = MockXMLHttpRequest 2xhr.XDomainRequest = MockXDomainRequest
No vulnerabilities found.
No security vulnerabilities found.