浅析Fetch API

  fetch()方法与XMLHttpRequest类似,fetch也可以发起ajax请求,但是与XMLHttpRequest不同的是,fetch方式使用promise,相比较XMLHttpRequest更加简洁。

一、Fetch是什么

1、Fetch 是一个现代的概念,等同于 XMLHttpRequest。它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性。

  Fetch 提供了对 Request 和 Response (以及其他与网络请求有关的)对象的通用定义。

  Fetch 还利用到了请求的异步特性——它是基于 Promise 的。

2、Fetch API 提供的一组对象

  window.fetch 函数只是 Fetch API 提供的众多接口中的一个,还有很多有用的对象:

  • window.Headers
  • window.Response
  • window.Request
  • ……

3、不需要依赖第三方库,就可以优雅地使用 AJAX

  Fetch API 提供了能够用于操作一部分http的 JavaScript 接口,比如requests 和 responses,它同时也提供了一个全局的 fetch() 方法,能够简单的异步的获取资源。使用 window.fetch 函数可以代替以前的 $. ajax、$.get 和 $.post。

二、缘起

1、XMLHttpRequest

(1)所有的功能全部集中在同一个对象中,容易书写出混乱、不易维护的代码

(2)采用传统的事件驱动模式,无法适配新的Promise API

2、Fetch API

(1)并非取代AJAX,而是对AJAX传统 API的改进

(2)精细的功能分割:头部信息、请求信息、响应信息等均分布到不同的对象,更利于处理各种复杂的 AJAX 场景

(3)使用 Promise API,更利于异步代码的书写

(4)Fetch API 并非 ES6内容,而是属于 HTML5 新增 Web API

3、Fetch 是浏览器提供的原生 AJAX 接口。

  由于原来的XMLHttpRequest不符合关注分离原则,且基于事件的模型在处理异步上已经没有现代的Promise等那么有优势。因此Fetch出现来解决这种问题。

二、基本使用

  使用fetch函数即可立即向服务器发送网络请求。fetch方法接受一个表示url的字符串或者一个Request对象作为参数,第二个参数可选,包含配置信息,返回值为Promise对象。

1、请求配置对象

  • method: 字符串, 请求方法, 默认值是 GET
  • headers: 对象, 请求头信息
  • body: 请求体的内容, 必须匹配请求头中的 Content-Type
  • mode: 字符串, 请求模式
  • credentials: 如何携带凭据( cookie )
  • cache: 配置缓存模式
    • default: 表示 fetch 请求之前将检查下http的缓存
    • no-store: 表示 fetch 请求将完全忽略 http 缓存的存在。这意味着请求之前将不再检查下http 的缓存, 拿到响应后, 它也不会更新 http 缓存
    • no-cache: 如果存在缓存, 那么 fetch 将发送一个条件查询 request 和一个正常的 request, 拿到响应后, 它会更新 http 缓存.
    • reload: 表示 fetch 请求之前将忽略 http 缓存的存在, 但是请求拿到响应后, 它将主动更新 http 缓存
    • force-cache: 表示 fetch 请求不顾一切的依赖缓存, 即使缓存过期了, 它依然从缓存中读取, 除非没有任何缓存, 那么它将发送一个正常的 request
    • only-if-cached: 表示 fetch 请求不顾一切的依赖缓存, 即使缓存过期了, 它依然从缓存中读取. 如果没有缓存, 它将抛出网络错误( 该设置只是 mode为"same-origin"时有效 )
2、返回值

  fetch 函数返回一个 Promise 对象

  • 当收到服务器的返回结果后, Promise 进入 resolved 状态, 状态数据为 Response 对象
  • 当网络发生错误( 或其他导致无法完成交互的错误 ) 时, Promise 进入 rejected 状态, 状态数据为错误信息
3、Response 对象
  • ok : boolean, 当响应消息码在 200 ~ 299 之间时为 true, 其他为 false
  • status: number, 响应的状态码
  • text(): 用于处理文本格式 Ajax 响应. 它从响应中获取文本流, 将其读完, 然后返回一个被解决为 String对象的 Promise
  • blob(): 用于处理二进制文件格式 (比如图片或电子表格) 的 Ajax 响应. 它读取文件的原始数据, 一旦读取完整个文件, 就返回一个对解决为 blob 对象的 Promise.
  • json(): 用于处理 JSON 格式的 Ajax 的响应. 它将 JSON 数据流转换为一个被解决为 JavaScript 对象的 Promise.
  • redirect(): 可以用于重定向到另一个 url. 它会创建一个新的 Promise, 以解决来自重定向的 URL 的响应.

4、fetch请求分3种格式

(1)本地目录文本格式

(2)本地目录json格式

(3)网络请求格式

5、基本的fetch请求

fetch('url地址')//第一个参数url是必须填的,
.then(function(res){
    //res中存放的是response响应内容
    //console.log(res.json())会打印一个promise对象
    //response是只能被读取一次的,console.log取一次,return取一次,会报错
    return res.json();//返回一个promise对象
    //  res.json()     返回的数据类型是json 格式
    //  res.text()     返回的是文本格式
    //  res.blob()     处理 二进制  主要针对 图片  以及 流
}).then(function(myJson){
    console.log(myJson)//数据在此处打印出来
    //前一个没有返回值则会显示undefined
})

  执行第一个then方法中的return res.json();会返回一个新的Promise实例对象

  执行第二个then方法会根据前面promise对象的状态发生变化来调用的

6、解释两次then用法:

  第一次then用法:then是根据promise的状态变化而执行的回调函数,promise的状态变化由resolve()函数决定,then的参数为resolve函数传递出来的数据,直接输出res是一个对象不是我们需要的数据,使用res.json()或者res.test()获取到我们需要的数据。

  res.json() / res.text() 获取到的是一个新的promise实例,arr.txt 的值在[[[PromiseResult]]里面,但是直接取是取不出来的。没有方法取出来,Promise的设计文档中说了,[[PromiseResult]]是个内部变量,外部无法得到,只能在then中获取。所以就会用到第二次then了。

  第一个 then 的return返回值是一个promise实例对象,所以回调链转交给了新的实例对象,第二个then的回调函数参数为PromiseValue的值,当返回值不是对象,而是数据类型时,会将该返回值赋值给PromiseValue,供下次的then函数使用

7、fetch号称ajax替代品,使用了ES6中的Promise对象。

  优点如下:语法简洁,基于标准 Promise 实现,支持 async/await

  缺点如下:

(1)fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理。

(2)fetch默认不会带cookie,需要添加配置项。

(3)fetch不支持abort(正在支持中),不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费。

(4)fetch没有办法原生监测请求的进度,而XHR可以。

posted @ 2019-08-22 22:58  古兰精  阅读(463)  评论(0编辑  收藏  举报