The next generation of Ajax technology - the learning and use of Fetch

1. Getting to know fetch

insert image description here

Fetch is called the next-generation Ajax technology , which uses Promise to process data. Is a concise and clear API, than XMLHttpRequestmore simple and easy to use.

XMLHttpRequest

Let's take a look at the code for implementing a simple ajax request using pure XMLhttpRequest:

//获取XMLHttpRequest实例对象
const xhr = new XMLHttpRequest();
//初始请求
xhr.open("get", "https://jsonplaceholder.typicode.com/users");
//发送数据
xhr.send();
//设置xhr请求状态修改回调
xhr.onreadystatechange = function () {
    
    
    //如果请求状态已完成时
    if (xhr.readyState === 4) {
    
    
        //如果响应状态码大于等于200并且小于300时
        if (xhr.status >= 200 && xhr.status < 300) {
    
    
            //请求成功
            console.log(JSON.parse(xhr.response));
        } else {
    
    
            //请求失败
            console.log("请求失败!");
        }
    }
};

Please don't confuse XMLHttpRequest with Ajax. Ajax is just an idea or technology, and XMLHttpRequest is a native object that can be used to implement Ajax.

fetch

Fetch is a modern concept equivalent to XMLHttpRequest. It provides many of the same features as XMLHttpRequest, but is designed to be more scalable and efficient.
Note that Fetch is a native API provided by JavaScript, so it can be used directly. We also use fetch to request the interface of the previous example:

fetch("https://jsonplaceholder.typicode.com/users")
  .then((res) => res.json())
  .then((data) => console.log(data));

It can be seen that fetch is the returned Promise instance, which can be directly chained and called, the code is simpler and easier to understand, and async and await can also be used.

Axios

Axios Chinese official website
can actually find that the usage of fetch and axios is very similar, because the browser side of Axios is actually the XMLHttpRequest结合Promiseresult of encapsulation.
Therefore, fetch can actually directly replace Axios to initiate browser-side requests, directly using native ones!
insert image description here

Two, fetch configuration

Since fetch can replace axios, fetch must be the same as axios, and many options can be configured to complete different requests, such as obtaining data, modifying data, uploading files, etc...

configuration

Promise<Response> fetch(input[, init]);

The first parameter input is 定义要获取的资源. this might be:

  • A USVString containing the URL of the resource to fetch. Some browsers will accept blob: and data: as schemes. A
  • Request object. The fetch method can also accept a second parameter (optional), as a 配置对象custom HTTP request to issue.

The second argument (init) is an optional arguments object:

fetch(url, {
    
    
    method: "GET",//请求方法 默认get
    headers: {
    
    //配置请求头
        "Content-Type": "text/plain;charset=UTF-8"
    },
    body: data,//请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
    referrer: "about:client",// 一个 USVString 可以是 no-referrer、client 或一个 URL。默认是 client。
    referrerPolicy: "no-referrer-when-downgrade",//指定了 HTTP 头部 referer 字段的值。可能为以下值之一:no-referrer、 no-referrer-when-downgrade、origin、origin-when-cross-origin、 unsafe-url。
    mode: "cors",//请求的模式,如 cors、no-cors 或者 same-origin。
    credentials: "same-origin",// 请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie,必须提供这个选项。
    cache: "default",// 请求的 cache 模式:default、 no-store、 reload 、 no-cache、 force-cache 或者 only-if-cached。
    redirect: "follow",//可用的 redirect 模式:follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误),或者 manual (手动处理重定向)。在 Chrome 中默认使用 follow(Chrome 47 之前的默认值是 manual)
    integrity: "",//包括请求的 subresource integrity 值(例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。
    keepalive: false,//而这个参数是在说,即使页面已经不在了,这个请求依然需要完成,因此浏览器会延长它的生存期。
    signal: undefined//配合AbortController完成请求中断操作
});

3. Commonly used objects and methods

fetch() adopts a modular design, and the API is scattered on multiple objects (Response object, Request object, Headers object), which makes the written code more reasonable and the logic clearer.

Request

The Request MDN document
mentioned earlier that the first parameter of fetch can be a Request object.

var myRequest = new Request(input[, init]);

It seems to be similar to the parameters of fetch().

instance method

arrayBuffer()

The arrayBuffer() method of the Request interface reads 请求体it and returns it as a promise which will be fulfilled one ArrayBuffer.

const myArray = new Uint8Array(10);

const request = new Request('/myEndpoint', {
    
    
  method: 'POST',
  body: myArray
});

request.arrayBuffer().then(function(buffer) {
    
    
  // do something with the buffer sent in the request
});

blob()

The blob() method of the Request interface reads the request body and returns it as a promise that will fulfill a Blob.

const obj = {
    
    hello: 'world'};
const myBlob = new Blob([JSON.stringify(obj, null, 2)], {
    
    type : 'application/json'});

const request = new Request('/myEndpoint', {
    
    
  method: 'POST',
  body: myBlob
 });

request.blob().then(function(myBlob) {
    
    
  // do something with the blob sent in the request
});

clone()

The clone() method in the Request interface can create a copy of the current Request object.

formData

The formData() method of the Request interface reads the request body and returns it as a promise that will fulfill a FormData object.

const formData = new FormData();
const fileField = document.querySelector('input[type="file"]');

formData.append('username', 'abc123');
formData.append('avatar', fileField.files[0]);

const request = new Request('/myEndpoint', {
    
    
  method: 'POST',
  body: formData
});

request.formData().then(function(data) {
    
    
  // do something with the formdata sent in the request
});

json()

The json() method of the Request interface reads the request body and returns it as a promise that will fulfill a JSON parsed from the text of the response body.

Note that although the method is named json(), the result is not JSON, but the input is parsed as JSON to produce one JavaScript 对象.

Returns a Promise that will fulfill a JavaScript object. This object could be anything that can be represented in JSON - an object, an array, a string, a number...

const obj = {
    
    hello: 'world'};

const request = new Request('/myEndpoint', {
    
    
  method: 'POST',
  body: JSON.stringify(obj)
 });

request.json().then(function(data) {
    
    
  // do something with the data sent in the request
});

text()

The text() method of the Request interface reads the request body and promisereturns promise that will fulfill a String. Responses are always decoded using UTF-8.

Response

You can use the Response.Response() constructor to create a Response object, but it is usually more likely that other API operations return a Response object.

let r = new Response(); 
console.log(r); 
// Response { 
// body: (...) 
// bodyUsed: false //包含了一个布尔值 (en-US)来标示该 Response 是否读取过 Body。
// headers: Headers {} //包含此 Response 所关联的 Headers 对象。
// ok: true //包含了一个布尔值,标示该 Response 成功(HTTP 状态码的范围在 200-299)。
// redirected: false //表示该 Response 是否来自一个重定向,如果是的话,它的 URL 列表将会有多个条目。
// status: 200 //包含 Response 的状态码(例如 200 表示成功)。
// statusText: "OK" //包含了与该 Response 状态码一致的状态信息(例如,OK 对应 200)。
// type: "default" //包含 Response 的类型(例如,basic、cors)。
// url: "" //包含 Response 的 URL。
// } 

static method

error()

The error() method of the Response interface returns a new Response object containing information about network errors.

redirect()

The redirect() method of the Response interface returns a Response that can be redirected to the specified URL.

var response = Response.redirect(url, status);

instance method

arrayBuffer

The method arrayBuffer() on Response accepts a Response stream and waits for its reading to complete. It returns a promise instance, and resolves an ArrayBuffer object.

response.arrayBuffer().then(function(buffer) {
    
    
  // do something with buffer
)};

blob

The **blob()** method of the Response mixin takes a Response stream and reads it to completion. It returns a promise that resolves with a Blob.

response.blob().then(function(myBlob) {
    
    
  // do something with myBlob
});

clone

The clone() method of the Response interface creates a clone of the Response object, identical in all respects, but stored in different variables.
clone() throws TypeError if the response body has already been used. In fact, the main reason clone() exists is to allow body objects to be used multiple times (when they are single-use).

const image1 = document.querySelector('.img1');
const image2 = document.querySelector('.img2');

const myRequest = new Request('flowers.jpg');

fetch(myRequest).then((response) => {
    
    
  const response2 = response.clone();

  response.blob().then((myBlob) => {
    
    
    const objectURL = URL.createObjectURL(myBlob);
    image1.src = objectURL;
  });

  response2.blob().then((myBlob) => {
    
    
    const objectURL = URL.createObjectURL(myBlob);
    image2.src = objectURL;
  });
});

formData

The formData() method in the Response object reads and encapsulates the data stream carried in the Response object into an object. This method will return a Promise object, which will generate a FormData object.

response.formData()
.then(function(formdata) {
    
    
  // do something with your formdata
});

json

The json() method of the Response mixin receives a Response stream and reads it to completion. It returns a Promise, and the resolve result of the Promise is to parse the text body into JSON.

response.json().then(data => {
    
    
  // do something with your data
});

Returns a object 解析为 JSON 格式的 promise 对象, which can be anything 由 JSON 表示的东西- an object, an array, a string, a number...

text

The text() method of the Response mixin provides a "return stream" (Response stream) for reading, and reads it to completion. It returns a Promise object containing a USVString object (that is, text), and the encoding of the returned result is always UTF-8.

response.text().then(function (text) {
    
    
  // do something with the text response
});

Headers

The Headers interface of the Fetch API allows you to perform various operations on HTTP request and response headers. These operations include retrieve, set, add and delete. A Headers object has an associated list of headers, which is initially empty and consists of zero or more key-value pairs.

Constructor Headers()

var myHeaders = new Headers(init);

The init parameter is optional: Preset your Headers with an object containing arbitrary HTTP headers. Can be a ByteString 对象; or a 已存在Headers object.

append()

Inside a Headers object, the append() method of the Headers interface can append a new value to existing headers, or add a header that does not exist.

myHeaders.append(name,value);

delete()

The delete() method can delete the specified header from the Headers object.
The following reasons will cause this method to throw a TypeError:

  1. The header name does not exist in the HTTP header.
  2. header is locked.
myHeaders.delete(name);

entries()

Headers.entries() returns all key-value pairs in the Headers object in the form of an iterator.

// Create a test Headers object
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'text/xml');
myHeaders.append('Vary', 'Accept-Language');

// Display the key/value pairs
for (var pair of myHeaders.entries()) {
    
    
   console.log(pair[0]+ ': '+ pair[1]);
}

forEach()

Similar to the forEach method of traversing an array.

// Create a new test Headers object
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Cookie", "This is a demo cookie");
myHeaders.append("compression", "gzip");

// Display the key/value pairs
myHeaders.forEach((value, key) => {
    
    
  console.log(`${
      
      key} ==> ${
      
      value}`);
})

return

compression ==> gzip
content-type ==> application/json
cookie ==> This is a demo cookie

get()

Get the value of the specified headers attribute.

const myHeaders = new Headers(); // Currently empty
myHeaders.get('Not-Set'); // Returns null

has()

The **has()** method of the Headers interface returns a Boolean value to declare whether a Headers object contains the specified header information.

myHeaders.append('Content-Type', 'image/jpeg');
myHeaders.has('Content-Type'); // Returns true
myHeaders.has('Accept-Encoding'); // Returns false

keys()

The headers.keys() method returns an iterator composed of all the keys of the headers (Object) object. The headers object can be traversed through the iterator, and the element keys in the returned iterator are all strings.

// 创建一个 Headers 对象
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'text/xml');
myHeaders.append('Vary', 'Accept-Language');

// 显示 Headers 中所有的 key
for(var key of myHeaders.keys()) {
    
    
   console.log(key);
}

set()

The difference between Headers.set and append() is that when the specified header already exists and allows to receive multiple values, Headers.set will 重写此值为新值and append() will 追加到值序列的尾部.

myHeaders.set('Accept-Encoding', 'deflate');
myHeaders.set('Accept-Encoding', 'gzip');
myHeaders.get('Accept-Encoding'); // Returns 'gzip'

values()

The Headers.values() method returns an iterable value, through which the value of the key-value pair in Headers can be traversed. The returned value is a ByteString object.

// Create a test Headers object
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'text/xml');
myHeaders.append('Vary', 'Accept-Language');

// Display the values
for (var value of myHeaders.values()) {
    
    
   console.log(value);
}
text/xml
Accept-Language

The above content is all referenced in mdn web docs - Fetch API

Guess you like

Origin blog.csdn.net/ZHANGYANG_1109/article/details/127996511