The target
- A simple Ajax implementation
- A brief introduction to the use of FETCH
The main points of
What is the Ajax
-
The core is XMLHTTPRequest
-
AJAX = Asynchronous JavaScript and XML.
-
AJAX is not a new programming language, but a new way to use existing standards.
-
AJAX is the art of exchanging data with a server and updating parts of a web page without reloading the entire page.
Common browser request/response headers/error code parsing
The specific meaning of each parameter can be found at 😛
Common request header
- :method: GET
- :path:
- :scheme: https
- accept: application/json, text/plain
- accept-encoding: gzip, deflate, br
- cache-control: no-cache
- cookie: deviceId=c12;
- origin:
- referer:
- The 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.1
Commonly used the response headers
- access-control-allow-credentials: true
- Access-control-allow-origin: https://domian/service // The browser only allows requests for resources from the current domain and does not trust resources from other domains
- content-encoding: gzip
- content-type: application/json; charset=UTF-8
- date: Thu, 06 Aug 2020 08:15:05 GMT
- 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
Commonly used status
- 200 get success
- 201 post success
- 301 permanent redirect
- 302 Temporary redirect
- 304 Negotiation cache server file is not modified
- 400 The client request has a syntax error and cannot be recognized by the server
- 403 The server is requested but refuses to provide service, possibly across domains
- 404 requested resource not found
- Method requested by 405 is not allowed
- 500 An unexpected error occurs on the server
Let’s start with a simple implementation
When readyState changes, the onReadyStatechange event is emitted
Graph TD xhr. onReadyStatechange --> 0: request not initialized --> 1: server connection established --> 2: request received --> 3: request processing --> 4: request completed and response ready
let xhr = new XMLHttpRequest();
xhr.open('GET'.'http://domain/service');
// Request State change event Changed from 0 to 4
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);
// start request
xhr.send();
❔ why send methods are processed last
Copy the code
fetch
The 🌐 browser has a new API with promises built in to handle responses through the then method
- Cookies are not included by default
- Error does not reject
- Timeout Settings are not supported
- AbortController is needed to abort fetch
Look at the example without ink
fetch('http://domain/service', {
method: 'GET'.credentials: 'same-origin' // Control before sending cookies and two values include
}).then(response= > {
if(response.ok) {
return response.json()
}
throw new Error('http error')
}).then(json= > { // chain call
console.log(json)
}).catch(error= > {
console.error(error)
})
// It is not supported to set the timeout directly, you can implement it with promise
function fetchTimeout(url, init, timeout = 3000) {
return new Promise((resolve, reject) = > {
fetch(url, init)
.then(resolve) // For example, after 1000ms, the request response is completed, and the state of promise is changed to pity; after 3000ms, the final result will not be modified, and the state of Pormise is irreversible
.catch(reject);
setTimeout(reject, timeout); })}Copy the code
How do I abort fetch ❔
/ / 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
How is fetch implemented ❓ using TS ❗
interface IOptions {
url: string, type? :'GET' | 'POST'.data: any, timeout? : number }// Process the queryString parameter of the GET request
function formatUrl(object) {
// a=xxx&b=xxx querystring
let dataArr = []
for(let key in object) {
dataArr.push(`${key}=The ${encodeURIComponent(object[key])}`)}return dataArr.join('&')}export function ajax(options: IOptions = {
url: ' ',
type: 'GET',
data: {},
timeout: 3000
}) {
return new Promise((resolve, reject) = > {
// Prevent bypass type checking ajax({} as any) from being used in this way
if(! options.url) {return
}
const dataToQueryString = formatUrl(options.data)
let timer = null
let xhr = null
// Request processing timed out
const onStateChange = () = > {
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 ((window as any).XMLHttpRequest) {
xhr = new XMLHttpRequest
} else {
/ / compatible with IE
xhr = new ActiveXObject('Microsoft.XMLHTTP')}if (options.type.toUpperCase() === 'GET') {
xhr.open('GET'.`${options.url}?${dataToQueryString}`);
onStateChange();
xhr.send();
} else if (options.type.toUpperCase() === 'POST') {
xhr.open('POST', options.url);
xhr.setRequestHeader(
'ContentType'.'application/x-www-form-urlencoded'
);
onStateChange();
xhr.send(options.data);
}
// Request timeout processing
if (options.timeout) {
timer = setTimeout(() = > {
xhr.abort();
reject('timeout'); }, options.timeout); }})}Copy the code
➰ Happy times go by very quickly, and it’s time to say goodbye ➰