Fetch API

Fetch API 提供了一个 JavaScript 接口, 用于发起http请求。是浏览器自带的JavaScript API。

XMLHttpRequest一样,都是用来跨网络异步获取资源。但fetch比起XMLHttpRequest() 使用起来更简洁、方便

有一些差别,具体如下:

1. fetch()使用 Promise ,不使用回调函数,因此大大简化了写法,写起来更简洁。

2. fetch()采用模块化设计,API 分散在多个对象上(Response 对象、Request 对象、Headers 对象),更合理一些;相比之下,XMLHttpRequest 的 API 设计并不是很好,输入、输出、状态都在同一个接口管理,容易写出非常混乱的代码

3. fetch()通过数据流(Stream 对象)处理数据,可以分块读取,有利于提高网站性能表现,减少内存占用,对于请求大文件更实用。而 XMLHTTPRequest 对象不支持数据流,所有的数据必须放在缓存里,不支持分块读取,必须等待全部拿到后,再一次读出来。

4. 从 fetch() 返回的 Promise 不会被标记为 reject, 即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。

5. 

fetch 默认不会发送 cookies。除非你使用了credentials 的初始化选项

一.  基本使用

fetch()接受一个 URL 字符串作为参数,默认向该网址发出 GET 请求,返回一个 Promise 对象。

fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  })
  .catch(function(error) {
    console.log(error)
  })
复制代码

上面示例中,fetch()接收到的response是一个 Stream 对象response.json()是一个异步操作,取出所有内容,并将其转为 JSON 对象。

也可以传入第二个可选参数,用来配置 初始化 对象,(详细配置参考:  文档):

fetch(url, {
    body: JSON.stringify(data),
    headers: {
      'content-type': 'application/json'
    },
    method: 'POST'
  })
  .then(response => response.json())
  .then(data => {
    console.log(data)
  })
复制代码

二. Response对象

fetch()请求成功以后,得到的是一个 Response 对象。它对应服务器的 HTTP 回应。

const response = await fetch(url);
复制代码

response 包含的数据通过 Stream 接口异步读取,但是它还包含一些同步属性,对应 HTTP 回应的标头信息(Headers),可以立即读取。

async function fetchRequest() {
  const response = await fetch(url);
  console.log(response.status); 
  console.log(response.statusText);
}
复制代码

上面示例中,response.statusresponse.statusText就是 Response 的同步属性,可以立即读取。

response  有以下属性:

Response.ok属性返回一个布尔值,表示请求是否成功,true对应 HTTP 请求的状态码 200 到 299,false对应其他的状态码

Response.status属性返回一个数字,表示 HTTP 回应的状态码(例如200,表示成功请求)

Response.statusText属性返回一个字符串,表示 HTTP 回应的状态信息(例如请求成功以后,服务器返回”OK”)

Response.url属性返回请求的 URL。如果 URL 存在跳转,该属性返回的是最终 URL。

Response.type属性返回请求的类型。可能的值如下:

  • basic:普通请求,即同源请求。
  • cors:跨域请求。
  • error:网络错误。

Response.redirected属性返回一个布尔值,表示请求是否发生过跳转。

 Response.headers 属性:

Response.headers属性,指向一个 Headers 对象,对应 HTTP 回应的所有标头。

Headers 对象可以使用for...of循环进行遍历。

const response = await fetch(url);

for (let [key, value] of response.headers) { 
  console.log(`${key} : ${value}`);  
}
复制代码

Headers 对象提供了以下方法,用来操作标头:

  • Headers.get():根据指定的键名,返回键值。
  • Headers.has(): 返回一个布尔值,表示是否包含某个标头。
  • Headers.set():将指定的键名设置为新的键值,如果该键名不存在则会添加。
  • Headers.append():添加标头。
  • Headers.delete():删除标头。
  • Headers.keys():返回一个遍历器,可以依次遍历所有键名。
  • Headers.values():返回一个遍历器,可以依次遍历所有键值。
  • Headers.entries():返回一个遍历器,可以依次遍历所有键值对([key, value])。
  • Headers.forEach():依次遍历标头,每个标头都会执行一次参数函数。

这些方法中,最常用的是response.headers.get(),用于读取某个标头的值。

let response =  await  fetch(url);  
response.headers.get('Content-Type')
// application/json; charset=utf-8
复制代码

Headers.keys()Headers.values()方法用来分别遍历标头的键名和键值

// 键名
for(let key of myHeaders.keys()) {
  console.log(key);
}

// 键值
for(let value of myHeaders.values()) {
  console.log(value);
}
复制代码

读取Response对象的方法:

Response对象根据服务器返回的不同类型的数据,提供了不同的读取方法。

  • response.text():得到文本字符串。
  • response.json():得到 JSON 对象。
  • response.blob():得到二进制 Blob 对象。
  • response.formData():得到 FormData 表单对象。
  • response.arrayBuffer():得到二进制 ArrayBuffer 对象。

注意: 上面5个读取方法都是异步的,返回的都是 Promise 对象。

Response.clone() 方法

Stream 对象只能读取一次,读取完就没了。这意味着,前一节的五个读取方法,只能使用一个,否则会报错。

let text =  await response.text();
let json =  await response.json();  // 报错
复制代码

上面示例先使用了response.text(),就把 Stream 读完了。后面再调用response.json(),就没有内容可读了,所以报错。

Response 对象提供Response.clone()方法,创建Response对象的副本,实现多次读取。

const response1 = await fetch('flowers.jpg');
const response2 = response1.clone();

const myBlob1 = await response1.blob();
const myBlob2 = await response2.blob();

image1.src = URL.createObjectURL(myBlob1);
image2.src = URL.createObjectURL(myBlob2);
复制代码

上面示例中,response.clone()复制了一份 Response 对象,然后将同一张图片读取了两次。

Response.body 属性

Response.body属性是 Response 对象暴露出的底层接口,返回一个 ReadableStream 对象,供用户操作。

三: fetch()完整 API

fetch()第二个参数的完整 API 如下。

const response = fetch(url, {
  method: "GET",
  headers: {
    "Content-Type": "text/plain;charset=UTF-8"
  },
  body: undefined,
  referrer: "about:client",
  referrerPolicy: "no-referrer-when-downgrade",
  mode: "cors", 
  credentials: "same-origin",
  cache: "default",
  redirect: "follow",
  integrity: "",
  keepalive: false,
  signal: undefined
});
复制代码

cache

cache属性指定如何处理缓存。可能的取值如下:

  • default:默认值,先在缓存里面寻找匹配的请求。
  • no-store:直接请求远程服务器,并且不更新缓存。
  • reload:直接请求远程服务器,并且更新缓存。
  • no-cache:将服务器资源跟本地缓存进行比较,有新的版本才使用服务器资源,否则使用缓存。
  • force-cache:缓存优先,只有不存在缓存的情况下,才请求远程服务器。
  • only-if-cached:只检查缓存,如果缓存里面不存在,将返回504错误。

mode

mode属性指定请求的模式。可能的取值如下:

  • cors:默认值,允许跨域请求。
  • same-origin:只允许同源请求。
  • no-cors:请求方法只限于 GET、POST 和 HEAD,并且只能使用有限的几个简单标头,不能添加跨域的复杂标头,相当于提交表单所能发出的请求。

credentials

credentials属性指定是否发送 Cookie。可能的取值如下:

  • same-origin:默认值,同源请求时发送 Cookie,跨域请求时不发送。
  • include:不管同源请求,还是跨域请求,一律发送 Cookie。
  • omit:一律不发送。

跨域请求发送 Cookie,需要将credentials属性设为include

fetch('http://another.com', {
  credentials: "include"
});
复制代码

signal

signal属性指定一个 AbortSignal 实例,用于取消fetch()请求

redirect

redirect属性指定 HTTP 跳转的处理方法。可能的取值如下:

  • follow:默认值,fetch()跟随 HTTP 跳转。
  • error:如果发生跳转,fetch()就报错。
  • manualfetch()不跟随 HTTP 跳转,但是response.url属性会指向新的 URL,response.redirected属性会变为true,由开发者自己决定后续如何处理跳转。

以上就是fetch API 的全部内容。

参考:

1. 阮一峰网络日志

2. MDN

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享