current position:Home>The next generation of Ajax technology - the learning and use of Fetch

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

2022-11-24 22:39:30Yancy

一、初识fetch

在这里插入图片描述

Fetch被称为下一代Ajax技术,采用Promise方式来处理数据.Is a concise and clearAPI,比XMLHttpRequest更加简单易用.

XMLHttpRequest

Let's look at using pure firstXMLhttpRequestTo achieve a simpleajax请求的代码:

//获取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("请求失败!");
        }
    }
};

请不要把XMLHttpRequest和Ajax弄混了,AjaxJust an idea or technique,而XMLHttpRequestis a native object,Can use him to achieveAjax.

fetch

Fetch 是一个现代的概念,等同于 XMLHttpRequest.它提供了许多与 XMLHttpRequest 相同的功能,但被设计成更具可扩展性和高效性.
注意,Fetch是JavaScript提供的原生API,所以是可以直接使用的,我们同样使用fetchTo request the interface of the previous example:

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

可以看到,fetch是返回的Promise实例,Chain calls can be made directly,The code is simpler and easier to understand,也可以使用async和await.

Axios

Axios中文官网
其实可以发现,fetch和axiosare used in a very similar way,因为AxiosThe browser side actually isXMLHttpRequest结合PromiseThe encapsulation result of.
因此,fetchIn fact, it can be directly replacedAxiosTo make browser-side requests,直接用原生的!
在这里插入图片描述

二、fetch配置

既然说fetch可以代替axios,那么fetch肯定和axios一样,Many options can be configured,to fulfill different requests,For example fetching data、修改数据、上传文件等等……

配置

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

第一个参数input是Defines the resources to fetch.这可能是:

  • 一个 USVString 字符串,包含要获取资源的 URL.一些浏览器会接受 blob: 和 data: 作为 schemes. 一个
  • Request 对象. fetch方法还可以接受第二个参数(可选),作为配置对象,定制发出的 HTTP 请求.

第二个参数(init)is an optional parameter 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,//And this parameter is saying,Even if the page is no longer there,This request still needs to be fulfilled,So the browser will prolong its lifetime.
    signal: undefined//配合AbortControllerComplete request interrupt operation
});

三、Commonly used objects and methods

fetch()采用模块化设计,API 分散在多个对象上(Response 对象、Request 对象、Headers 对象),Makes the written code more reasonable,逻辑也更加清晰.

Request

Request MDN文档
前面说到fetch的第一个参数可以是一个Request对象.

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

与fetch()The parameters seem to be about the same.

实例方法

arrayBuffer()

Request 接口的 arrayBuffer() 方法读取请求体并将其作为一个 promise 返回,该 promise Will honor 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()

Request 接口的 blob() method reads the request body and passes it as promise 返回,该 promise Will honor one 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()

Request 接口中的clone() method can create a currentRequest 对象的副本.

formData

Request 接口的 formData() method reads the request body and passes it as promise 返回,该 promise Will honor one FormData 对象.

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()

Request 接口的 json() method reads the request body and treats it as one promise 返回,该 promise Will honor the one obtained by parsing the text of the response body JSON.

注意,Although the method is named json(),结果并不是 JSON,Instead, take the input as JSON 解析,以生成一个 JavaScript 对象.

Returning one will honor one JavaScript 对象的 Promise.This object may be any available JSON 表示的东西——一个对象、一个数组、一个字符串、一个数值……

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()

Request 接口的 text() method reads the request body and treats it as one promise 返回,该 promise Will honor one String.response is always used UTF-8 解码.

Response

你可以使用 Response.Response() 构造函数来创建一个 Response 对象,But usually the more likely scenario is,其他的 API 操作返回了一个 Response 对象.

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.
// } 

静态方法

error()

Response 接口的 error() method returns a new containing information about network errors Response 对象.

redirect()

Response 接口的 redirect() Method returns a redirection to the specified URL 的 Response .

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

实例方法

arrayBuffer

Response上的方法 arrayBuffer() 接受一个 Response 流,and wait for its read to complete.它返回一个 promise 实例,并 resolve 一个 ArrayBuffer 对象.

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

blob

Response mixin 的 **blob()**方法使用一个 Response 流,并将其读取完成.It returns a useBlob解决的 promise.

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

clone

Response 接口的 clone() method to create a clone of the response object,This object is identical in all respects,But stored in a different variable.
If the response body is already used,clone() 抛出 TypeError.事实上,clone() The main reason for being is to allow body Objects can 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

Response 对象中的formData() 方法将 Response The data stream carried in the object is read and encapsulated into an object,该方法将返回一个 Promise 对象,This object will yield a FormData 对象.

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

json

Response mixin 的 json() 方法接收一个 Response 流,并将其读取完成.它返回一个 Promise,Promise 的解析 resolve 结果是将文本体解析为 JSON.

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

返回一个被解析为 JSON 格式的 promise 对象,This can be anything由 JSON 表示的东西 - 一个 object,一个 array,一个 string,一个 number…

text

Response mixin 的 text() method provides a readable “返回流”(Response stream),and read it.它返回一个包含 USVString 对象(也就是文本)的 Promise 对象,The encoding of the returned result is always UTF-8.

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

Headers

Fetch API 的 Headers Interfaces allow you to pair HTTP Request and response headers perform various operations.These operations include retrieval,设置,添加和删除.一个 Headers Objects have an associated header list,它最初为空,Consists of zero or more key-value pairs.

构造函数Headers()

var myHeaders = new Headers(init);

init 参数可选:Pass an inclusive arbitrary HTTP headers object to preset yours Headers. 可以是一个ByteString 对象; 或者是一个已存在的 Headers 对象.

append()

在一个Headers对象内部,Headers接口的 append() method to append a new value to an existing one headers 上,Or add one that doesn't exist header.

myHeaders.append(name,value);

delete()

delete() 方法可以从 Headers Object to delete specified header.
The following reasons will cause the method to throw a TypeError:

  1. header 名在 HTTP header 中是不存在的.
  2. header 被锁定了.
myHeaders.delete(name);

entries()

Headers.entries() 以 迭代器 的形式返回 Headers 对象中所有的键值对.

// 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()

and iterate over the arrayforEach方法类似.

// 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}`);
})

返回

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

get()

获取指定headers属性的值.

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

has()

Headers 接口的 **has()**method returns a boolean to declare one Headers对象 Whether to include specific header information.

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

keys()

eaders.keys() 方法返回一个 headers(Object) 对象所有 key composed iterators,通过迭代器可以遍历 headers 这个对象,The elements in the returned iterator key 都是字符串.

// 创建一个 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()

Headers.set 和 append() The difference between the two is when specified header is already present and allows multiple values ​​to be received,Headers.set会Override this value with the new value,而append()会Append to the end of the sequence of values.

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

values()

Headers.values() The method returns an iterable of values,This value can be traversed Headers 中键值对的 value 值.返回的 value 都是 ByteString 对象.

// 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

copyright notice
author[Yancy],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/328/202211242238462047.html

Random recommended