Manipulating HTTP content in a browser without reloading any window or form requires the use of JavaScript asynchronous techniques.

HTTP specifies how WEB browsers get documents and content like forms from the WEB server, and how the WEB server responds to those requests and submissions. WEB browsers handle a lot of HTTP. In general, HTTP is not under the control of JavaScript scripts and only happens when the user clicks a link, submits a form, and enters a URL. However, it is possible to manipulate HTTP with JavaScript code. Setting the Location property of the Window object with a script or calling the Submit () method of the form object initializes the HTTP request. In both cases, the browser reloads the page. ———— The Definitive JavaScript Guide

First, some knowledge of HTTP

(1) Request message

1. Components of the request message

  • The starting line
  • The first
  • The main body

2. A brief introduction to the start line of the request message

(1) Method: Used to tell the server what to do.

  • GET: Obtains a document from the server
  • HEAD: Fetch only the header of the document from the server
  • POST: sends data to be processed to the server
  • PUT: Stores the body of the request on the server
  • TRACE: Traces the packets that may be sent to the server through the proxy server
  • OPTIONS: Determines which methods to execute from the server
  • DELETE: Deletes a document from the server

(2) request-URL specifies the path of the requested resource on the server.

A common format for < scheme > : / / < user >, < password > @ < host > : < port > / < path >; ?

#


#


#





(2) Response message

1. Components of response packets

  • The starting line
  • The first
  • The main body

2. A brief introduction to the start line of the response message

(1) Status: Used to tell the client what happened

  • 100-199(defined 100-101): message prompt
  • 200-299(200-206 defined): succeeded
  • 300-399(300-305 defined): Redirection
  • 400-499(defined 400-415): Client error
  • 500-599(definition 500-505): server error

(2) Reason-phrase provides textual explanation for the status code, which is paired with the status code.

(3) Packet flow

A, AJAX

AJAX: A communication protocol that uses scripts to manipulate HTTP and WEB servers to exchange data without causing page reloads.

Reference: developer.mozilla.org/zh-CN/docs/…

Use AJAX to do two things:

  • Send the request to the server without reloading the page.
  • Accept and use data sent from the server.

(I) Using AJAX to communicate with the server

Step 1: First have an object to do these things

// Old compatibility code, no longer needed.
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
    httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6 and older
    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
Copy the code

Step 2: Following the subscribe, publish principle, define which function is called back to process the response when the response status changes

httpRequest.onreadystatechange = function(){
    // Process the server response here.
};
Copy the code

Step 3: Initialize and send the request

/ / initialize request httpRequest. Open (' GET 'and' http://www.example.org/some.file ', true); Httprequest.send ();Copy the code

1. Xmlhttprequest. open(method, URL, async) function

We know that the start line of the request message contains method and request-URL parameters. These parameters need to be specified when the open() function is called, corresponding to the first parameter and the second parameter. The third parameter indicates whether the request is synchronous or asynchronous.

2. Xmlhttprequest. send(body) function

Body is an optional parameter that serves as the body of the request; If the request method is GET or HEAD, the request body should be set to NULL, which defaults to null without assignment. If the request method is POST, you need to specify the request body.

(2) How to write the function that handles the response in step 2

1, how do you know where communication process step: XMLHttpRequest. ReadyState

It can also be expressed as: 0 (request not initialized), 1 (server link established), 2 (request accepted), 3 (request being processed), 4 (request completed and response ready).

XMLHttpRequest. The readyState value for XMLHttpRequest. DONE or 4 is to complete a server response to receive communications from time to time

Xmlhttprequest.status = xmlHttprequest.status

The value is an integer and is a standard HTTP status code. A value in the range of 2xx indicates success. Until the request completes, the status value is 0. Note that the status returned by the browser is also 0 if XMLHttpRequest fails.

3, communication subject of how to obtain a response packet success: XMLHttpRequest. The responseText and XMLHttpRequest responseXML.

  • XMLHttpRequest.responseText– The server returns a text character.
  • XMLHttpRequest.responseXML– returned as an XMLDocument object, which can then be processed using JavaScript.

To sum up, the first step of the response processing function should determine whether the communication is over and the response can be obtained, and then determine the processing result (status code) of the server side. If the processing is successful, it will read the desired message. The framework is as follows

if (httpRequest.readyState === XMLHttpRequest.DONE) {
    // Everything is good, the response was received.
    if (httpRequest.status === 200) {
        // Perfect!
    } else {
        // There was a problem with the request.
        // For example, the response may have a 404 (Not Found)
        // or 500 (Internal Server Error) response code.
    }} else {
    // Not ready yet.
}
Copy the code

In the event of a communication error (such as a server down), an exception is thrown in the access response status onReadyStatechange method. To mitigate this, try… Catch the top if… Else statement wrapped around it.

(3) The header and body of the request packet when the POST request is sent

The entity header provides a lot of information about the entity and its contents and can tell the message receiver (the server) what it is processing. Part of the entity header is the Content header, where the Content-Type header represents the object Type of the request body, that is, the data Type that the client tells the server to actually send. When the HTTP POST method sends data to the server, the request body Type is specified by the Content-Type header.

1. Request header: XMLHTTPRequest(XHR) Method for setting content-Type

XMLHttpRequest. SetRequestHeader (header, value) : set the value of the HTTP request header. The setRequestHeader() method must be called after open() but before send(). If content-type is set, the header is set to “content-type”.

Request body: The body of the XMLHTTPRequest request is used as an argument to the send() method

3. Setting of header when XHR sends different subjects

  • Request subject is simple text: Content-type is set to ‘text/plain; Charset = utF-8 ‘, can not set, request body incoming automatically set.
  • The request subject is form data (form data in the form a=1&b=2&c=3) : Content-Type should be set to ‘Application/X-www-form-urlencoded’, it can be left unset, request body incoming will be set automatically.
  • The request subject is complex FormData (including upload file FormData, FormData data) : Content-type set to ‘multipart/form-data’, FromData request body incoming automatically set developer.mozilla.org/zh-CN/docs/…
  • Request subject is JSON data (json.stringfy () serializes Jason objects) : Content-type is set to ‘application/ JSON ‘.

4. Content-type syntax

Content-Type:

;

;


  • Media-type: MIME type of a resource or data
  • Charset: character encoding standard, US-ASCII: ASCII character encoding. Ios-8859-x: x can be 1,2,5,6,7,8,15. It is a set of European character codes. Ios-8859-1 is an 8-bit extension to ASCII to support multiple western European languages. Utf-8: UTF-8 character encoding. (Default encoding)
  • Boundary: A boundary that is required in a multipart entity to encapsulate multiple parts of a message.

Second, the axios

Documents: www.npmjs.com/package/axi…

You can build a server using jSON-server and learn in three steps,

Documents: www.npmjs.com/package/jso…

Axios sends a request and returns a Promise object. The methods used to send the request are listed as follows:

(1) AIXOS sends requests

1. The Axios API sends the request

  • axios(config)

    Axios ({method:”get”, url: “http://localhost:3000/posts/1” }).then((response)=>{ console.log(response.data) })

  • axios(url[,config])

    axios(‘/user/12345’); The default method is get, without specifying config

The request method alias API sends the request

  • Axios.request (config) — sends various requests

  • Axios. Get ([url, config]) – get request

  • Axios. Delete ([url, config]) – delete request

  • Axios. Head ([url, config]) – the head request

  • Axios. Options ([url, config]) – OPTION request

  • Axios.post (url[, data[, config]]) — Post the request

  • Axios.put (URL [, data[, config]]) — put request

  • axios.patch(url[, data[, config]])

    Axios. request({method:”get”, url: “Http://localhost:3000/comments/1”}). Then ((response) = > {the console. The log (response)}) / / get request axios.get(“http://localhost:3000/comments/1″).then((response)=>{ console.log(response) }) / / post request axios. Post (” http://localhost:3000/comments “, {” body “:” hello, “” postId” : 1 }).then((response)=>{ console.log(response) })

3. Create an axios instance that sends the request

  • axios.create([config])

When an instance of axios is created, it is used to send requests in the same way as axios used in (1).

You can reuse some basic Config configuration to create instances, and you can create different instances to connect to different servers.

 const instance=axios.create({
	baseURL:"http://localhost:3000",
	timeout:3000
});
instance({
	method:"GET",
	url: "/posts/1"
}).then((response)=>{
	console.log(response.data)
})
Copy the code

4. Parameter passing

You can select different parameter transmission modes based on service requirements, such as route configuration and background interface requirements.

(1) Pass parameters in query mode (this memory can be associated with the splicing of query parameters in database query)

axios.get('/user? ID=12345')Copy the code

(2) Parameter transmission in Params mode

A:

axios.get('/user/12345');
Copy the code

Method 2:

axios.get('/user', {
    params: {
      ID: 12345
    }
  })
Copy the code

(2) AiXOS features and functions

1. Intercept requests and responses

You can intercept a request or response before the then/catch methods process the response data. For example, according to the response returned by the background interface, a process is performed to determine whether the user has logged in. Whether the user has logged in or not follows different logic, and the response can be intercepted.

Response interception: We know that “2XX” is the status code of the server processing success, the other is the status code of the error, the interceptor can do some interception for these cases.

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  }, function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    return Promise.reject(error);
  });
Copy the code

An example of response interception:

Two functions, promise.resolve () and promise.reject (), are often used to manually create a resolve or reject Promise shortcut.

axios.interceptors.response.use(function (response) { let res= response.data; If (res.status==0){return res.data; Elseif (res.status==10){// Elseif (res.status==10){window.location.href="/#/login"; return Promise.reject(res); }else{ console.log(res.msg) return Promise.reject(res); } }, function (error) { console.log(error); // Handle error codes other than 2xx return promise.reject (error); });Copy the code

2. Cancel request: Refer to official documentation if necessary

Third, the Promise

There’s a great video on promise at Site B:

www.bilibili.com/video/BV1GA…

MDN Reference documentation

Developer.mozilla.org/zh-CN/docs/…

Developer.mozilla.org/zh-CN/docs/…

(1) What is Promise? Why use it?

A Promise is an object that represents the final completion or failure of an asynchronous operation. Is a solution to asynchronous programming. A Promise object has two important properties: the [[PromiseState]] state and the [[PromiseResult]] value.

Using promises, you can write out the success and failure of asynchronous tasks more elegantly. Especially in cases where an asynchronous task is completed and then the next asynchronous task is continued, using promises makes the code more readable. Look at the following code, which is a “callback hell” :

DoFirstSomething (function(firstResult) { DoSecondThing (firstResult, function(secondResult) { DoThirdThing (secondResult, function(finalResult) {console.log('Got the final result: '+ finalResult); }, failureCallback); }, failureCallback); }, failureCallback);Copy the code

Let doFirstSomething return a Promise object, which can be elegantly written like this using a promise. This is the chain call of a promise.

doSomethingFirst().then(firstResult=>{
   return doSecondThing(firstResult)
}).then(secondResult=>{
   return doThirdThing(secondeThing)
}).catch(failureCallback);
Copy the code

(2) The state of the Promise object

How does the Promise object represent the success and failure of an asynchronous task? Write code that lets a Promise specify success/failure conditions based on the result of an asynchronous task call when you create it.

  • Pending: The initial state that has neither been granted nor rejected.
  • This is a big pity: this will be fulfilled successfully. – The asynchronous task succeeded
  • Rejected: Indicates that the operation fails. — Asynchronous tasks fail

1. Ways to change the Promise state

Let p=new Promise((resolve,reject)=>{//1, resolve, pending=>fullfiled(resolved) //2,reject, Reject (' reject ') //pending=>reject (' reject ') // reject(' reject ')Copy the code

2. An example of creating a Promise that is treated as a success or failure based on the value of n as the result of an asynchronous task.

Let p=new Promise((resolve,reject)=>{setTimeout(()=>{let n=rand(1,100); console.log(n); if(n<=30){ resolve(n); }else{reject(n);} reject(n);} reject(n);} reject(n); // Set the state of the Promise object to failure, and pass the parameter value back to the failure callback method in then}},3000)});Copy the code

(3) Successful callback & failed callback & successful or unsuccessful callback

1, promise.prototype.then () : return a Promise**. ** This function can take two arguments, the first specifying the callback if the asynchronous task succeeds and the second specifying the callback if the asynchronous task fails. Grammar:

p.then(onFulfilled[, onRejected]);

p.then(value => {
  // fulfillment
}, reason => {
  // rejection
})
Copy the code

Prototype. Catch () : Return a Promise. This function specifies the callback when an asynchronous task fails, as the then() method only specifies the failed callback, not the successful callback. grammar

p.catch(onRejected); P.catch (function(reason) {// reject});Copy the code

Then (), catch(), and catch(). The powerful thing is that when you do a “chain call”, you can chain through it, catching and making n promise failed callbacks in one place, and writing less code than if you use THEN to define failure callbacks one by one.

let p=new Promise((resolve,reject)=>{ //reject("NO"); Resolve (" YES ")}) p.t hen (value = > {throw (" wrong ")}), then (value = > {the console. The log (222); }).then(value=>{ console.log(333); }). Catch (error=>{// Catch can catch any of the above promise exceptions console.log(error); })Copy the code

3, Promise. Prototype. Finally () and returns a Promise. At the end of the promise, the specified callback function will be executed, whether the result is fulfilled or Rejected. Grammar:

p.finally(onFinally); Of (function() {// return state (resolved or rejected)});Copy the code

To sum up, assuming doSomething() returns a Promise object, a relatively complete Promise framework is as follows:

doSomething().then(function(response) {
    //success,process response
  }) .catch(function(error) { 
    //fail,process error}).finally(function() {
    //do something whether success or fail 
});
Copy the code

(4) how to understand chain call

Chain call: One asynchronous task completes and the next asynchronous task continues

What is the decision to execute the NTH (n>=2) asynchronous task? Depending on the state of the Promise returned by its previous THEN (), the successful callback of the next THEN () is executed if it succeeds, the failed callback of the next THEN () or catch() is executed if it fails, and the chain call is skipped if it is undetermined.

The callback function has the following execution results:

let p=new Promise((resolve,reject)=>{ resolve("OK"); }) let result= p.tenn (value=>{//1, this error is rejected //throw "error"; //2, this error is resolved; Return new promise ((resolve,reject)=>{//resolve("oh yes"); reject("oh no"); }) },error=>{ alert(error) })Copy the code

The state of the PROMISE returned by the THEN method is determined by the result returned by the callback function specified by the THEN.

(1) If an exception is raised, the new promise is rejected, and reason is rejected.

(2) If an arbitrary value is returned that is not a PROMISE, the new promise becomes resolved and value is the returned value;

(3) If a new promise is returned, the result of this promise becomes the result of the new promise.

(5) Interrupt Promise

Terminally chained calls are made if and only if a Promise object in a pending state is returned from the THEN () method.

let p=new Promise((resolve,reject)=>{ resolve("YES") }) p.then(value=>{ console.log(111); Return new Promise(()=>{}) // Interrupt Promise}). Then (value=>{console.log(222); }). Then (value=>{console.log(333); }). Catch (error=>{console.log(error); })Copy the code

(6) Transform some old callback apis into Promises

1. SetTimeout function encapsulation

const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); Wait (10000). Then (() => {saySomething("10 seconds")}). Catch (failureCallback);Copy the code

2. Ajax encapsulation

function sendAJAX(url){ const p=new Promise((resolve,reject)=>{ let xmlhttp=new XMLHttpRequest(); xmlhttp.open("GET",url); xmlhttp.send(); xmlhttp.onreadystatechange=function(){ if(xmlhttp.readyState==4&&xmlhttp.status==200){ resolve(xmlhttp.responseText); } else{reject(xmlHTTP. status+","+xmlhttp.readyState);} else{reject(xmlhttp.status+","+xmlhttp.readyState); // Set the state of the Promise object to failure, and pass the parameter values back to the failure callback method in then}}}); return p; } sendAJAX("https://api.apiopen.top/getJoke").then((value)=>{ console.log(value); },(err)=>{ console.log(err) })Copy the code

Four, async&await

Async and await are syntactic candy based on promises, allowing us to write asynchronous behavior based on Promises in a more concise way, without intentionally chain-calling promises.

Async — Returns a Promise

The async keyword declares a function that returns a Promise object. The state of the Promise is determined by the return value of this function:

1. The return value is a non-PROMISE object, which is fullfiled, and the result value is the returned value

2. The return value is a Promise object, determined by the result of the Promise execution

async function test(){ // return "abc"; Resolve (" ABC ") return new Promise((resolve,reject)=>{//resolve("OK") // succeed //reject("ERR") // fail Throw (" HHHH ") // fail})}Copy the code

(2) await — return the [[PromiseResult]] value of the waiting Promise

The await operator is used to wait for a Promise object. It can only be used in async function. Await expression suspends execution of the current async function until the Promise processing completes. Grammar:

[return value] = await expression;Copy the code

The expression to the right of await is typically a Promise object, but it can be any other type of value

1. If the expression is a Promise object, and the Promise is fulfilled normally, the resolve function parameter of its callback will be the value of await expression and async function will be continued. If a Promise handles an exception (Rejected /throw error), await an exception (rejected/throw error), and await an exception (rejected/throw error). Catch Catch processing.

2. If the expression is any other value, return this value directly as await.

async function test(){ let p= new Promise((resolve,reject)=>{ //resolve("yeah ok") reject("oh no") }); //let res=await p; //let res=" ABC "try{let res=await p; }catch(e){ console.log(e); }}}Copy the code

(3) how to concisely call async and await Promise chain

MDN Reference Documents: developer.mozilla.org/zh-CN/docs/…

“Await expression suspends the execution of the current async function until the Promise completes.” Based on this, all operations in the chain waiting for the Promise to complete, except the last THEN, are placed in await function. A Promise corresponds to an await. This achieves the effect of a chain call.

1. Chain call form of Promise

fetch('coffee.jpg')
.then(response => response.blob())
.then(myBlob => {
  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
})
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
Copy the code

Async and await forms

async function myFetch() {
  let response = await fetch('coffee.jpg');
  let myBlob = await response.blob();

  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
}

myFetch()
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
Copy the code

Since await itself also returns a Promise object, the above code can be further optimized with promises.

async function myFetch() { let response = await fetch('coffee.jpg'); let myBlob = await response.blob(); return myBlob; } myFetch().then(myBlob=>{ let objectURL = URL.createObjectURL(myBlob); let image = document.createElement('img'); image.src = objectURL; document.body.appendChild(image); }).catch(e => { console.log('There has been a problem with your fetch operation: ' + e.message); });Copy the code

Wait for multiple asynchronous tasks to complete before continuing

Promise.all() : This method takes an iterable of promises. In general, it passes an Array of Promise objects. The return value is a Promise object;

(1) The state of n Promise objects in the parameter is fulfilled or this parameter is empty (for example, []), then the state of the returned Promise object is fulfilled, and the value is an array.

(2) There is a Promise object whose state is Rejected, so the returned Promise object is Rejected;

(3) The other cases are called pending states.

MDN Reference Documents: developer.mozilla.org/zh-CN/docs/…

Here is a typical example from MDN:

const promise1 = Promise.resolve(3); const promise2 = 42; Const promise3 = new Promise((resolve, reject) => {setTimeout(resolve, 100, 'foo'); }); Promise.all([promise1, promise2, promise3]).then((values) => { console.log(values); }); // expected output: Array [3, 42, "foo"]Copy the code