Browser-side high availability front-end request solution
- Easily handle Ajax cached data, front-end request concurrency
- Easy "debounce" and "throttle" operation
- Interceptor of request and response
- Request cancellation
- Failure retry
- Chained call of class Promise
- Automatically convert JSON type response data
use npm:
$ npm install hajax
use script:
<script src="release/dist/hx.min.js"></script>
Execute GET
request
import hx from 'hajax'
// Request a restful api for testing
hx.get('http://jsonplaceholder.typicode.com/users/1')
.then(function (response) {
// success handler
console.log(response);
})
.catch(function (error) {
// error handler
console.log(error);
})
Execute POST
request
// Request a restful api for testing
hx.post('/posturl')
.then(function (response) {
// success handler
console.log(response);
})
.catch(function (error) {
// error handler
console.log(error);
})
Execute concurrent requests: all
(blocking)
function getOne() {
return hx.get('/geturl1');
}
function getTwo() {
return hx.get('/geturl2');
}
hx.all([getOne(), getTwo()])
.then((function (responses) {
// The method here will be executed when all the requests in the all method are executed successfully.
// "responses" is an ordered array containing the data returned by the above two requests, arranged in the order of the parameters
}));
If you want to use this API and don't want to be blocked by a failed request, you can try the following
Execute concurrent requests: all
(non-blocking)
function getOne() {
return new Promise(function (resolve, reject) {
hx.get('/geturl1')
.then(function (resp) {
resolve(resp)
})
.catch(function () {
resolve()
})
})
}
function getTwo() {
return new Promise(function (resolve, reject) {
hx.get('/geturl2')
.then(function (resp) {
resolve(resp)
})
.catch(function () {
resolve()
})
})
}
hx.all([getOne(), getTwo()])
.then((function (responses) {
// Here, traversing the response parameters to determine whether the response is undefined, it means the request failed.
}));
Handle requests and data caching more easily with hajax
Normal
working process:
- Determine if there is cached data
- Send a request if it does not exist, and get the response data and put it in the cache
- Subsequent requests to read cached data
Cache strategy:
After the first request is successful, subsequent requests will use the cache. In the same request concurrent scenario (generally caused by poor code writing), multiple identical requests will be sent at the same time; the expiration time is generally from Save data and start calculating
Disadvantage:
Inconvenient to use, the method needs to be encapsulated by itself, and the concurrent request is cache invalidation, which increases maintenance costs.
hajax:
working process:
- Determine if there is cached data
- Determine if the cache policy is met
- Send a request, if the cache policy is satisfied, put the obtained response data into the cache
- The next request that satisfies the cache policy determines whether the cache expires
- Read the cache directly if it has not expired, and regain the data refresh cache when it expires
Cache strategy:
After the first request is sent, the cache buffer is opened and the cache expiration time is calculated. All requests before the expiration time will be placed in the callback trigger of the request buffer, after the first request is completed. Time to distribute data to the callback buffer waiting for requests to be processed
Disadvantage:
By default, when the first request fails, all subsequent requests will fail. The solution here may be for discussion. You can add the retry retry mechanism by adding retryLimit
to the first request (my idea) Is to prepare an automatic retry switch, the number of retries is the current number of the same request)
//Configuring the cache with "setStrategy"
//Generate a cache policy with "createStrategy"
hx.setStrategy(
hx.createStrategy('http://hajax.test/index.php', 4000, false)
)
//Send requests directly and cache data
hx.get('http://hajax.test/index.php').then(function (resp) {
console.log('success', resp)
}).catch(function (resp) {
console.log('failed', resp)
})
setTimeout(function () {
//Get cached data directly
hx.get('http://hajax.test/index.php').then(function (resp) {
console.log('success', resp)
}).catch(function (resp) {
console.log('failed', resp)
})
setTimeout(function () {
//Cache expired, re-requesting to get data
hx.get('http://hajax.test/index.php').then(function (resp) {
console.log('success', resp)
}).catch(function (resp) {
console.log('failed', resp)
})
}, 3000)
}, 3000)
-
exp(required):
- url
- RegExp
- '*'
-
bufferTime (default:-1; cache fresh after window refresh): buffer time
-
autoRetry (default:true): The number of retries is as follows: the number of caching requests before the end of the request except for the main request (the request actually sent out);
Custom requests can be made by passing the relevant configuration to a specific request
// Send a POST request using the "request" method
hx.request({
method: 'post',
url: '/url',
data: {
name: 'bennnis'
}
});
// Use the post method directly
hx.post('/url', {
name: 'bennnis'
});
In order to more conveniently call the corresponding request method, I provide the corresponding alias for all the request methods.
Use a function to handle concurrent requests better
You can create a new instance with a specific attribute to fit an unconventional situation that might appear in the system.
The new instance is identical to the default hx
instance.
//main.js
const hxDriver = hx.create({
baseURL: 'http://www.domain.org/api/v1/',
timeout: 1000,
headers: {'X-Custom-Header': 'foo'}
});
export default hxDriver
//app.js
import hxDriver from 'main'
hxDriver.request(config)
.then(function (resp) {
// handle success
})
.catch(function (err) {
// handle error
})
Parameters other than url
are optional.
{
// `url`
// Request address (required): can be relative and absolute
public url: string
// `method`
// Request method
public method: string // default: 'get'
// `baseURL`
// Request address prefix. When 'url' is a relative path, baseURL is added to the final request address.
public baseURL: string // default: '/'
// `headers`
// Request headers
public headers: object // default: {'Content-Type': 'application/json'}
// `params`
// The final request to the parameters in the url, as an object type
// Will stitch the corresponding key-value to the back of the request url
public params: object
// `data`
// The data to be sent as the request body is only valid at "post"
public data: object
// `timeout`
// Timeout of request: in milliseconds, the request for timeout will be automatically terminated
public timeout: number
// `withCredentials`
// Whether to use a certificate similar to cookies, authorization headers or TLS client certificates to create a cross-site access-control request
public withCredentials: boolean
// `responseType`
// Returns the type of response data. It allows manual settings to return the type of data. If it is set to an empty string, it will use the default "text" type.
// The enumeration types have the following six types 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
public responseType: string // default: 'text'
// `progressHandler`
// handler xhr progress change event
public progressHandler: Function
// `aborted`
// Identifier requesting termination
public aborted: boolean
// `retryLimit`
// Number of retries for failed requests
public retryLimit: number
// `retryBuffer`
// Retry interval for failed requests
public retryBuffer: number
// `mode`
// There are two request modes in hx: no default
// 'deboucne': Only send the last request within a certain time (debounceTime)
// 'trottle': When a request is sent, it must be separated by a certain time (throttleTime) before the next request can be sent.
public mode: string
// `debounceTime`
// Interval in 'debounce' mode
public debounceTime: number // default: 300
// `throttleTime`
// Interval in 'throttle' mode
public throttleTime: number // default: 3000
}
The response for a request contains the following information.
{
// `data`
// is an object transformed by response schema data
public data: any
// `status`
// is response status code
public status: number
// `statusText`
// is the HTTP status message from the server response `statusText` is the HTTP status message from the server respo
public statusText: string
// `headers`
// the headers that the server responded with
// All header names are lower cased
public headers: object
// `config`
// is the config that was provided to `hajax` for the request
public config: object
// `request`
// HRequest instance which produce this response
public request: HRequest
}
You can access these parameters in the callback function that responds to success and error catching.
hx.get('/api')
.then(function (resp) {
console.log(resp.data);
console.log(resp.status);
console.log(resp.statusText);
console.log(resp.headers);
console.log(resp.config);
})
.catch(function (resp) {
// The same response object can be accessed here, and subsequent operations may be considered in other more appropriate forms.
console.log(resp.data);
console.log(resp.status);
console.log(resp.statusText);
console.log(resp.headers);
console.log(resp.config);
});
You can configure the default parameters by configuring global instances, which are mixed into each request.
hx.config.baseURL = '/api';
hx.config.headers['Auth'] = 'request-auth-token';
// Consider adding a header configuration for the specified request type:
// hx.config.headers.post['Auth'] = 'xxx';
// Configuration settings default settings at creation time
const instance = hx.create({
baseURL: '/api'
});
// Continue to configure on the instance
instance.config.headers['Auth'] = 'request-auth-token';
The specific configuration on the request will override the global configuration
const instance = hx.create();
// Configure timeouts for all requests
instance.defaults.timeout = 2500;
// The final timeout for this request is 5000 milliseconds, covering the common configuration
instance.get('/longRequest', {
timeout: 5000
});
Before the request is sent and after the request is processed by the user, some specific processing can be done on the request.
// Request interceptor
hx.setRequestInterceptor(function (config) {
config.url = 'http://jsonplaceholder.typicode.com/users/1'
})
// Response interception
hx.setResponseInterceptor(function (resp) {
if (resp.status === 401) window.location = '/login'
})
You can terminate a request that is being sent or not sent by the abort
method provided in hx
// Get the returned request instance
const r = hx.get('http://hajax.test/index.php')
.then(function (resp) {
// success handler
}).catch(function (resp) {
// error handler
})
// abort request
r.abort()
The all
method and race
in HAjax
use Promise. If you need to use these two methods, make sure that Promise support exists in the execution environment: native or use [polyfill] (https://github.com/ Stefanpenner/es6-promise)
- Changelog
- Upgrade Guide
- Ecosystem
- Contributing Guide
- Code of Conduct
Solve some problems caused by multi-component and multi-request development under enterprise-level multi-person collaboration, and integrate some best practices in requests
The first edition is mainly to solve the basic request usage scenarios, and can quickly introduce optimization of project implementation requests, which will continue to improve and add more functions
MIT