Fetch of network requests and remote resources

Fetch API

The Fetch API can perform all the tasks of XHR objects, but it is easier to use and has a more modern interface. It can be used in modern Web tools such as Web worker threads XHR can choose asynchronous, and Fetch must be asynchronous

Fetch itself is an excellent tool for using JS to request resources. At the same time, this API can also be applied to service threads, providing interception, redirection and modification of the request interface generated by fetch()

1, Basic usage

The fetch() method is exposed in the global scope, including the homepage execution thread, module and worker thread. When this method is called, the browser will send a request to the given URL

1. Assignment request

fetch() has only one required parameter input. In most cases, this parameter is the URL of the resource to be obtained. This method returns a promise

 let r = fetch('/bar');
 console.log(r);//Promise<pending>

The format of URL (relative path, absolute path) is interpreted the same as XHR object

When the request is completed and the resources are available, the appointment is resolved as a Response object. This object is the encapsulation of the API, through which the corresponding resources can be obtained Get the properties and methods of the object to be used by the resource, master the Response and convert the load into a useful form

fetch('/bar.txt').then((response)=>{
        console.log(response);
      })

2. Read response

The easiest way to read the response content is to obtain the content in plain text format, which requires the * * text() * * method. This method returns an appointment and will solve the problem of obtaining the complete content of the resource

fetch('/bar.txt').then((response)=>{
        response.text()
        .then((data)=>{
            console.log(data);
        })
      })
fetch('/bar.txt').then((response)=>{
       response.text();
      }).then((data)=>{
        console.log(data);
      })

3. Processing status code and request failed

The Fetch API supports checking the status of the Response through the status and statustext attributes of the Response. A request that successfully obtains a Response usually generates a status code with a value of 200

 fetch('/bar').then((response)=>{
        console.log(response.status);
        console.log(response.statusText);
      })
//response. The value of status is 200 and the value of response If the value of statustext is ok, the request is successful

Requesting resources that do not exist usually generates a status code with a value of 404:

 fetch('/bar').then((response)=>{
        console.log(response.status);
        console.log(response.statusText);
      })
//response. The value of status is 404 and the value of response If the value of statustext is Not Found, the request has an error

If the requested URL throws a server error, a status code with a value of 500 will be generated:

 fetch('/bar').then((response)=>{
        console.log(response.status);
        console.log(response.statusText);
      })
//response. The value of status is 500 and the value of response If the value of statustext is Internal Server Error, the request has an error

Although the request may fail (for example, the status code is 500), only the scheduled resolution processing function is executed. In fact, as long as the server returns a response, the fetch() schedule will be resolved. This behavior is reasonable: the system level network protocol has successfully completed the round-trip transmission of messages. As for the true "successful" request, it needs to be defined when processing the response

Generally, when the status code is 200, it will be considered as successful, and other cases can be considered as unsuccessful To distinguish these two cases, you can check the ok property of the Reponse object when the status code is not 200 ~ 299

The browser timed out because the server did not respond, so the real fetch() failure will result in the appointment being rejected

fetch('/hangs-forever').then((response)=>{
        console.log(response);
     },(err)=>{
       console.log(err);
     })

Violating CORS, no network connection, HTTPS mismatch and other browser / network policies will lead to the rejection of the appointment

You can check the full URL used when sending the request through fetch() through the URL attribute

4. Custom options

When only URL is used, fetch() will send a GET request, which only contains the minimum request header. To further configure how to send the request, you need to pass in the optional second parameter init object

Please check the filling rules of init object by yourself

2, Common Fetch request modes

Like XHR, fetch() can send and receive data. Use the init object parameter to configure various serialized data sent by fetch() in the request body

1. Send JSON data

let payload = JSON.stringify({
        foo:'bar'
       });
       let jsonHeaders = new Headers({
        'Content-type':'application/json'
       });
       fetch('/send-me-json',{
        method:'POST',//A TTP method must be used when sending the request body
        body:payload,
        headers:jsonHeaders
       })

2. Send parameters in the request body

Because the request body supports any string value, you can send request parameters through it:

 let payload = 'foo=bar&&baz=qux';

       let paramHeaders = new Headers({
        'Content-type':'application/x-www-form-urlencoded; charset=UTF-8'
       });
       fetch('/send-me-json',{
        method:'POST',//A TTP method must be used when sending the request body
        body:payload,
        headers:paramHeaders
       })

3. Sending documents

Because the request body supports FormData implementation, fetch() can also serialize and send files in the file field:

let imageFormData = new FormData();
       let imageInput = document.querySelector("input[type=file]");
       imageFormData.append('image',imageInput.files[0]);

       fetch('/img-upload',{
        method:'POST',
        body:imageFormData
       })

It also supports sending multiple files:

let imageFormData = new FormData();
       let imageInput = document.querySelector("input[type='file'][multiple]");
      
       for(let i=0;i<imageInput.files.length;++i){
        imageFormData.append('image',imageInput.files[i]);
       }

       fetch('/img-upload',{
        method:'POST',
        body:imageFormData
       })

4. Send cross domain request

When requesting resources from different sources, the response must include CORS headers to ensure that the browser receives a response. Without these headers, cross domain requests will fail and throw errors

If the code does not need to access the response, it can also send a no CORS request. At this time, the type attribute value of the response is unique, so the content of the response cannot be read. This method is suitable for sending a probe request or caching the response for later use

fetch('//corss-origin.com',{
    method:'no-cors'
}).then((response)=>{
    console.log(response.type) // opaque
})

5. Interrupt request

Fetch APi makes an interrupt request by calling AbortController/AbortSignal. Calling AbortController.abort() will interrupt all network transmissions, which is especially suitable for situations where you want to stop transmitting large loads. Interrupting an ongoing fetch() request will result in a rejection with errors

let abortController = new AbortController();
       fetch('wikipedia.zip',{
        signal:abortController.signal
       }).catch((err)=>{
        console.log('aborted!');
       })

       //Interrupt request after 10ms
       setTimeout(()=>{
          abortController.abort();
       },10);

       //Has been interrupted

The following demonstrates the basic usage:

GET request:

01.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
       fetch('http://localhost:8080/Test_Fetch?UserName = Qi Tongwei & password = Sheng Tian Banzi '). Then ((response) = >{
        return response.json();
       }).then((data)=>{
        console.log(data);
       })
   </script>
</body>
</html>

server.js:

const express  = require('express');
const app = express();

app.use('*',function(req,res,next){
   // The allowed request host name and port number can also be wildcarded *, indicating that all host requests are allowed
   res.setHeader('Access-Control-Allow-Origin', '*');
   // Allow requests to carry cookie s
   res.setHeader('Access-Control-Allow-Credentials', true);
   // Allowed request methods
   res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
   // Allowed request headers
   res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

   next();
})


app.use('/Test_Fetch',(req,res)=>{
   console.log(req.query);
   let data = {
     UserName:req.query.UserName,
     PassWord:req.query.PassWord
   }
   res.send(JSON.stringify(data));
})

app.listen(8080);

Console printing:

{UserName: 'Qi Tongwei', PassWord: 'Shengtian Banzi'}

POST request:

01.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
       let data = {
        'UserName':'Qi Tongwei',
        'PassWord':'Shengtian Banzi'
       }
       fetch("http://localhost:8080/Test_Fetch",{
        method:'POST',
        "Access-Control-Allow-Origin" : "*",
        "Access-Control-Allow-Credentials" : true,
        headers:{
            'Content-Type':'application/json'
        },
        body:JSON.stringify(data)
       }).then((response)=>{
        return  response.json();
       }).then((data)=>{
        console.log(data);
       })
   </script>
</body>
</html>

server.js

const express  = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.use('*',function(req,res,next){
   // The allowed request host name and port number can also be wildcarded *, indicating that all host requests are allowed
   res.setHeader('Access-Control-Allow-Origin', '*');
   // Allow requests to carry cookie s
   res.setHeader('Access-Control-Allow-Credentials', true);
   // Allowed request methods
   res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
   // Allowed request headers
   res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

   next();
})

app.use('/Login',(req,res)=>{
   let data = {
      'UserName':req.query.UserName,
      'PassWord':req.query.PassWord
   }
   res.send(JSON.stringify(data));
})

app.post('/Test_Fetch',(req,res)=>{
   console.log(req.body);
   let data = {
      UserName:req.body.UserName,
      PassWord:req.body.PassWord
   }
   res.send(JSON.stringify(data));
})

app.listen(8080);

Console printing:

{UserName: 'Qi Tongwei', PassWord: 'Shengtian Banzi'}

ok, we'll talk about this in this issue. We'll continue to talk about webSocket in the next issue The above content is my personal understanding. If there is any error, please correct it!

Tags: Javascript Front-end network

Posted by nepton on Wed, 07 Sep 2022 22:48:58 +0530