首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Fetch API 使用

Fetch API 使用

作者头像
李振
发布2021-11-26 14:12:56
发布2021-11-26 14:12:56
1.6K00
代码可运行
举报
文章被收录于专栏:乱码李乱码李
运行总次数:0
代码可运行

背景

在上一章学习 React 组件的时候,想增加 React 对 Ajax 支持的内容,却发现网上的教程竟然用 jQuery 完成 Ajax 请求,个人觉得为了发送一个简单的请求引入 jQuery 库杀鸡焉用宰牛刀啊。其实 W3C 已经有了更好的替代品,那就是: Fetch API

Fetch API

Fetch API 的出现与 JavaScript 异步编程模型 Promise 息息相关,在 Fetch API 出现之前,JavaScript 通过 XMLHttpRequest(XHR) 来执行异步请求,XHR 将输入、输出和事件模型混杂在一个对象里,这种设计并不符合职责分离的原则。而且,基于事件的模型与 Promise 以及基于 Generator 的异步编程模型不太搭。

Fetch API 提供了对 HeadersRequestResponse 三个对象的封装,以及一个 fetch() 函数用来获取网络资源,并且在离线用户体验方面,由于 ServiceWorkers 的介入,Fetch API 也能提供强大的支持。

兼容性

fetch() 方法被定义在 window 对象中,你可以直接在控制台中输入 fetch() 查看浏览器是否支持,gitHub 上有基于低版本浏览器的兼容实现

简单示例

fetch() 方法接受一个参数——资源的路径。无论请求成功与否,它都返回一个 promise 对象,resolve 对应请求的 Response 对象。

代码语言:javascript
代码运行次数:0
运行
复制
let myImage = document.querySelector('.my-image');
fetch('https://lz5z.com/assets/img/avatar.png')
  .then(response => {
    if (!response.ok) return new Error(response);
    return response.blob();
  })
  .then(myBlob => {
    let objectURL = URL.createObjectURL(myBlob);
    myImage.src = objectURL;
  })
  .catch(err => {
    console.log(err);
  });

点击查看效果

在获取请求的 Response 对象后,通过该对象的 json() 方法可以将结果作为 JSON 对象返回,response.json() 同样会返回一个 Promise 对象,因此可以继续链接一个 then() 方法。相比传统的 XHR 的基于事件类型的编程方式,四不四简单很多哈。

Request 对象

Fetch API 引入了3个接口,它们分别是 Headers,Request 以及 Response 。他们直接对应了相应的 HTTP 概念,但是基于安全考虑,有些区别,例如支持CORS规则以及保证 cookies 不能被第三方获取。

通过 Request 构造器函数创建一个新的请求对象,这也是建议标准的一部分。 第一个参数是请求的 url,第二个参数是一个选项对象,用于配置请求。然后将 Request 对象传递给 fetch() 方法,用于替代默认的 url 字符串。

代码语言:javascript
代码运行次数:0
运行
复制
//不缓存响应结果, 方法为 GET
let req = new Request(url, {method: 'GET', cache: 'reload'});
fetch(req).then(response => {
  //
}).catch(err => {
  console.log(err);
});

除此之外,还可以基于 Request 对象创建新对象,比如将一个 GET 请求创建成为一个 POST 请求

代码语言:javascript
代码运行次数:0
运行
复制
let postReq = new Request(req, {method: 'POST'});
console.log(postReq.method); //"POST"

Headers 对象

每个 Request 对象都有一个 header 属性,在 Fetch API 中它对应了一个 Headers 对象。 我们可以使用 Headers 对象构建 Request 对象。而在 Response 对象中也有一个 header 属性,但是响应头是只读的。

Headers 接口是一个简单的多映射的名-值表

代码语言:javascript
代码运行次数:0
运行
复制
let headers = new Headers();
headers.append('Accept', 'application/json');
let request = new Request(url, {headers: headers});
fetch(request).then(response => {
  console.log(response.headers);
});

也可以传一个多维数组或者 json:

代码语言:javascript
代码运行次数:0
运行
复制
reqHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});
//操作 Headers 中的内容
reqHeaders.has("Content-Type") //true
reqHeaders.get("Content-Type") //"text/plain"
reqHeaders.set("Content-Type", "text/html")
reqHeaders.delete("X-Custom-Header");

Response 对象

构建 Respondse 对象有什么用呢?通常 Response 的内容在服务端生成,但是 Fetch API 是浏览器里面的内容啊。

对了,就是为了离线应用,通过 Service Worker 浏览器能够获取请求头的内容,然后通过在浏览器中构建响应头来替换来自服务器的响应头以达到构建离线应用的目的(这方面内容以后再说)。

构建方法

代码语言:javascript
代码运行次数:0
运行
复制
let response = new Response(
  JSON.stringify({photos: {photo: []}}),
    {status: 200, headers: headers}
);

steam 支持

Request 和 Response 对象中的 body 只能被读取一次,它们有一个属性叫 bodyUsed,读取一次之后设置为 true,就不能再读取了。

代码语言:javascript
代码运行次数:0
运行
复制
let res = new Response("one time use");
console.log(res.bodyUsed); //false
res.text().then(v => {
  console.log(v); //"one time use"
  console.log(res.bodyUsed); // true
});

这样设计的目的是为了之后兼容基于流的 API,让应用只能消费一次 data,这样就允许了 JavaScript 处理大文件例如视频,并且可以支持实时压缩和编辑。

clone 支持

如何让 body 能经得起多次读取呢?Fetch API 提供了一个 clone() 方法。调用这个方法可以得到一个克隆对象。不过要记得,clone() 必须要在读取之前调用,也就是先 clone() 再读取。

代码语言:javascript
代码运行次数:0
运行
复制
let res = new Response("many times use");
console.log(res.bodyUsed); //false
let clone = sheep.clone();
console.log(res.bodyUsed); //false

总结

虽然 Fetch API 提供了更加简洁的接口,Promise 形式的编程体验,但是它也不是完美的,最大的问题就是不能中断一个请求,并且无法检测一个请求的进度,这些在 XHR 中早就有很好的解决方案。也行 Fetch API 需要更多的时间。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-02-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
    • Fetch API
      • 兼容性
      • 简单示例
      • Request 对象
      • Headers 对象
      • Response 对象
      • steam 支持
      • clone 支持
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档