一、什么是 fetch?
在前端的发展历程中用于请求网络资源的方式主要有三种:从原生的 XMLHttpRequest 到 jQuery 的 Ajax 再到现在主流的 axios,其中 Ajax 和 axios 都是对 XMLHttpRequest 的封装(本质上都是使用 XMLHttpRequest 方法获取网络资源),这些封装库让开发者对 XMLHttpRequest 的使用变得更简单高效。然而 fetch 的推出使开发者对网络资源的异步请求多了一种可选方案(一般说 fetch 是 XMLHttpRequest 的替代方案),注意 fetch 不是对 XMLHttpRequest 的封装,它是 JavaScript 提供的原生的全局方法。
二、fetch 的简单使用
fetch(url) , url 为请求的网络资源路径。fetch() 返回的结果包裹在一个 Promise 对象里面, 故可使用 .then 接收, res 是 fetch 包装的一个原始对象,如果想要拿到后端返回的结果则需要使用 res.json() 获取到使用 Promise 包装的后端返回的(响应体 body)数据,所以 res2 才是后端返回的原始数据。
fetch('http://localhost:8000/getInfo').then(res=>{
console.log(res);
return res.json()
})
.then(res2=>{
console.log(res2)
})
.catch(error=>{
console.log(error);
})
以上代码打印结果
其他情况响应的数据结构
注意:只要相应成功 Promise 状态都为 resolve
响应成功且状态码 200
响应失败情况 (fetch 返回的 Promise 状态为 reject)
响应成功但状态码在 200~299 之外。ok 值为 false
三、fetch() 的第二个参数
fetch 的第二个参数是一个 init 配置对象。配置项如下:
fetch('http://localhost:8000/getInfo',{
method: 'get',
mode: 'XXX',
credentials: 'XXX',
// ...省略
})
- method: 请求方法,如 get、post、delete 等
- headers: 请求头信息配置
- body: 请求体信息,注意 get 和 head 请求不能包含 body 信息。
- mode: 请求模式,决定发起的是同源请求还是跨域请求,可选项:cors、no-cors、same-origin
- credentials: 请求的 credentials,为了在当前域名内自动发送 cookie,可选项: omit、same-origin、include
- cache: 请求的缓存模式,可选项:default、no-store、reload、no-cache、force-cache、only-if-cached
- redirect: 可用的 redirect 模式,可选项:follow、error、manual
- referrer: 设置请求来源,可用于资源防盗
- referrerPolicy: 用于指定 http 头部 referer 字段的值
四、fetch 的一些特点
- fetch 响应的结果是一个 Promise 对象
- 只要 fetch 的请求有响应,fetch() 返回的 Promise 状态都会标记为 resolve,即使响应的状态码不是 200 (404、502 其他)。只有 fetch() 无响应的时候返回的 Promise 状态才为 reject (一般网络问题或请求被拦截才会出现)。
- 当 fetch() 响应的 http 状态码不在 200 ~ 299 范围内时,fetch() 响应对象的 ok 值 为 false
- fetch() 的第一个参数也可以为 Request 对象, 效果和只传入一个 String 类型的 url 效果是一样的。
fetch(new Request('http://localhost:8000/getInfo'),{
method: 'get',
}).then(res=>{
console.log(res);
})
.catch(error=>{
console.log('出错了:',error);
})
五、终止 fetch 请求
- 使用 AbortController 接口的 abort() 方法能够终止 fetch 请求。
let controller = new AbortController();
let signal = controller.signal;
fetch('http://localhost:8000/getInfo',{
method: 'get',
signal
}).then(res=>{
console.log(res);
})
.catch(error=>{
console.log('出错了:',error);
})
// 发起请求后立即取消请求
controller.abort()
取消请求的情况
- 超时结束请求, 设置 10s 超时取消请求。
fetch(new Request('http://localhost:8000/getInfo'),{
method: 'get',
signal: AbortSignal.timeout(10000)
}).then(res=>{
console.log(res);
})
.catch(error=>{
console.log('出错了:',error);
})
六、主流浏览器对 fetch 的支持
- Chrome 42+
- Edge 14+
- Firefox 39+
本文含有隐藏内容,请 开通VIP 后查看