Ajax and FETCH API details
-
XMLHTTPRequest
-
fetch
- Cookies are not included by default
- Error does not reject
- Timeout Settings are not supported
- AbortController is needed to abort fetch
Common browser request/response headers/error code parsing
request header
:method: GET :path: /solar-comment/api/comment/tutor-primary-activity/senior-recommend/users/self? tagSource=&_productId=351&_appId=0
:scheme: https
accept: application/json, text/plain, */* accept-encoding: gzip, deflate, br cache-control: no-cache cookie: deviceId=c122305d338525616baea870cc76dd5b; abSeed=843447469b71b0978db580220c952c10; userid=172270653; persistent=3411agNdImBJd8GjTW6bWT9Vg0U2yoaka3Lp8sSCiv9B6MDvr27fL4o50ha+Pfuhi1y4/Gg8aRN3FEP+VV4jWA==; sid=5530384168693043754; sess=QvrAQ0Cq+EcDQQPTer2XHlv4fhIRaW/YCb/e4pz/I+vzKp85mI2ukPUBIuGweXj5sq8HhuYQtf03DxK4dphwkOyBKovyUyC5I8t9exQw6Aw= origin: https://m.yuanfudao.biz referer: https://m.yuanfudao.biz/primary/market/senior-recommend/reserve user-agent: Mozilla / 5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1Copy the code
response header
access-control-allow-credentials: true
access-control-allow-origin: https://m.yuanfudao.bizcontent-encoding: gzip content-type: application/json; charset=UTF- 8 -
date: Thu, 06 Aug 2020 08:15:05GMT set-cookie: sess=QvrAQ0Cq+EcDQQPTer2XHlv4fhIRaW/YCb/e4pz/I+uSfZtum4dPp9q4HJL5o+GWuDXHXQLQF2JrIgwzZPaZHWal4qYZy/cfW0Sle/fyB/w=; domain=.yuanfudao.biz; path=/; HttpOnly set-cookie: userid=172270653; domain=.yuanfudao.biz; path=/; HttpOnly status:200
Copy the code
status
200 Get succeeded 201 POST succeeded 301 Permanent Redirection 302 Temporary redirection 304 Negotiated cache server file is not modified 400 The client request has a syntax error and cannot be recognized by the server 403 The server receives the request but refuses to provide services. The resource requested across the domain 404 does not exist. The method requested by the 405 does not allow the 500 server to have unexpected errors
An example of sending a request and encapsulating a multi-browser-compatible request function
XMLHTTPRequest
let xhr = new XMLHttpRequest();
xhr.open('GET'.'http://domain/service');
// request state change event
xhr.onreadystatechange = function () {
// request completed?
if(xhr.readyState ! = =4) return;
if (xhr.status === 200) {
// request successful - show response
console.log(xhr.responseText);
} else {
// request error
console.log('HTTP error', xhr.status, xhr.statusText); }};// xhr.timeout = 3000; // 3 seconds
// xhr.ontimeout = () => console.log('timeout', xhr.responseURL);
The progress event can report long-running file uploads
// xhr.upload.onprogress = p => {
// console.log(Math.round((p.loaded / p.total) * 100) + '%');
// }
// start request
xhr.send();
Copy the code
fetch
fetch(
'http://domain/service', {
method: 'GET'
}
)
.then(response= > response.json())
.then(json= > console.log(json))
.catch(error= > console.error('error:', error));
// No cookies by default
fetch(
'http://domain/service', {
method: 'GET'.credentials: 'same-origin'})// Error not reject
// HTTP errors such as 404 Page Not Found or 500 Internal Server Error do Not cause the Fetch to return a Promise marked REJECT; .catch() is also not executed.
// To accurately determine whether the fetch is successful, include the promise resolved situation, and then determine whether response.ok is true
fetch(
'http://domain/service', {
method: 'GET'
}
)
.then(response= > {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
})
.then(json= > console.log(json))
.catch(error= > console.error('error:', error));
// It is not supported to set the timeout directly, use promise
function fetchTimeout(url, init, timeout = 3000) {
return new Promise((resolve, reject) = > {
fetch(url, init)
.then(resolve)
.catch(reject);
setTimeout(reject, timeout); })}/ / suspend the fetch
const controller = new AbortController();
fetch(
'http://domain/service', {
method: 'GET'.signal: controller.signal
})
.then(response= > response.json())
.then(json= > console.log(json))
.catch(error= > console.error('Error:', error));
controller.abort();
Copy the code
Try wrapping request methods in TypeScript
interface IOptions {
url: string; type? : string; data: any; timeout? : number; }function formatUrl(json) {
let dataArr = [];
json.t = Math.random();
for (let key in json) {
dataArr.push(`${key}=The ${encodeURIComponent(json[key])}`)}return dataArr.join('&');
}
export function ajax(options: IOptions) {
return new Promise((resolve, reject) = > {
if(! options.url)return;
options.type = options.type || 'GET';
options.data = options.data || {};
options.timeout = options.timeout || 10000;
let dataToUrlstr = formatUrl(options.data);
let timer;
/ / 1. To create
let xhr;
if ((window as any).XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
if (options.type.toUpperCase() === 'GET') {
/ / 2. The connection
xhr.open('get'.`${options.url}?${dataToUrlstr}`.true);
/ / 3. Send
xhr.send();
} else if (options.type.toUpperCase() === 'POST') {
/ / 2. The connection
xhr.open('post', options.url, true);
xhr.setRequestHeader('ContentType'.'application/x-www-form-urlencoded');
/ / 3. Send
xhr.send(options.data);
}
/ / 4. Receive
xhr.onreadystatechange = () = > {
if (xhr.readyState === 4) {
clearTimeout(timer);
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
resolve(xhr.responseText);
} else{ reject(xhr.status); }}}if (options.timeout) {
timer = setTimeout(() = > {
xhr.abort();
reject('timeout');
}, options.timeout)
}
// xhr.timeout = options.timeout;
// xhr.ontimeout = () => {
// reject(' reject ');
// }
});
}
Copy the code