由于 FetchAPI 是基于 Promise 设计,有必要先学习一下 Promise,推荐阅读 MDN Promise 教程
本文章内容推荐阅读 MDN Fetch 教程
语法说明
fetch(url, options).then(function(response) {
// handle HTTP response
}, function(error) {
// handle network error
})
<script>
fetch('http://localhost:3000/data').then((data) => {
/* text()方法属于fetchApi的一部分,它返回一个Promise实例对象 ,用于获取后台数据 -
再用`.then()`才可以获取数据 */
return data.text()
}).then(function (data) {
// 注意这里data得到的才是最终数据
console.log(data)
})
</script>
具体参数案例:
//兼容包
require('babel-polyfill')
require('es6-promise').polyfill()
import 'whatwg-fetch'
fetch(url, {
method: "POST",
body: JSON.stringify(data), // data can be `string` or {object}!
headers: {
"Content-Type": "application/json"
},
credentials: "same-origin"
}).then(function(response) {
response.status //=> number 100–599
response.statusText //=> String
response.headers //=> Headers
response.url //=> String
response.text().then(function(responseText) { ... })
}, function(error) {
error.message //=> String
})
url
定义要获取的资源。这可能是:
- 一个
USVString字符串,包含要获取资源的URL。 - 一个
Request对象。
options(可选)
一个配置项对象,包括所有对请求的设置。可选的参数有:
-
method: 请求使用的方法,如GET、POST、DELETE、PUT。 -
headers: 请求的头信息,形式为Headers对象或ByteString。 -
body: HTTP的请求参数,请求的body信息:可能是一个Blob、BufferSource、FormData、URLSearchParams或者USVString对象。注意GET或DELETE方法的请求不能包含body信息。 -
mode: 请求的模式,如cors、no-cors或者same-origin。 -
credentials: 请求的credentials,如omit、same-origin或者include。 -
cache: 请求的cache模式:default,no-store,reload,no-cache,force-cache, 或者only-if-cached。 options 是一个对象,可设置以下字段: -
method:请求方法,默认GET;
-
headers:请头信息,可以是简单的对象,也可以是
Headers的实例; -
body:发送数据。
Blod、bufferSource、FormData、URLSearchParams、USVstring,GET、HEAD 没有body; -
mode:请求模式。
- cors:跨域请求;
- no-cors:只允许使用
GET、HEAD、POST; - same-origin:同源请求;
- navigate:支持页面导航(不太明白)。
-
credentials:是否发送
cookies:- omit:不发送,默认;
- same-origin:同源发送;
- include:发送。
-
cache:缓存策略:
- default:请求之前检查缓存;
- no-cache:有缓存,发送一个查询请求,缓存失效,再发送正常请求;
- no-store:不检查缓存,直接请求;
- reload:忽略缓存,拿到响应后,更新缓存;
- force-cache:强制读取缓存,缓存过期,再发送正常请求;
- only-if-cached:读取缓存,过期就报网络错误。 mode 设置为
same-origin时有效。
-
redirect:重定向时的处理方法:
- follow:跟随;
- error:报错;
- manual:用户手动跟随。
-
integrity:包含一个验证资源完整性的字符串。
response
一个 Promise,resolve 时回传 Response 对象:
-
属性:
status (number)- HTTP请求结果参数,在100–599 范围statusText (String)- 服务器返回的状态报告ok (boolean)- 如果返回200表示请求成功则为trueheaders (Headers)- 返回头部信息,下面详细介绍url (String)- 请求的地址
-
方法:
text()- 以string的形式生成请求textjson()- 生成JSON.parse(responseText)的结果blob()- 生成一个BlobarrayBuffer()- 生成一个ArrayBufferformData()- 生成格式化的数据,可用于其他的请求
-
其他方法:
clone()Response.error()Response.redirect()
response.headers
has(name) (boolean)- 判断是否存在该信息头get(name) (String)- 获取信息头的数据getAll(name) (Array)- 获取所有头部数据set(name, value)- 设置信息头的参数append(name, value)- 添加header的内容delete(name)- 删除header的信息forEach(function(value, name){ ... }, [thisContext])- 循环读取header的信息
实例
get请求方式的参数传递 两种传参的方式:
?id=123 与 /123 等价
DELETE请求方式的参数传递:
POST两种请求方式的参数传递
PUT请求方式的参数传递
fetch响应结果
<script>
fetch('http://localhost:3000/data').then((data) => {
//return data.text()
return data.json()
}).then(function (data) {
//data.json()得到的是json对象,可以用data.name直接调用单个属性
//data.text()得到的是字符串,不能直接调用
//console.log(data)
console.log(data.name)
})
</script>
支持状况及解决方案
原生支持率并不高,幸运的是,引入下面这些 polyfill 后可以完美支持 IE8+ :
- 由于 IE8 是 ES3,需要引入 ES5 的
polyfill:es5-shim,es5-sham - 引入
Promise的polyfill:es6-promise - 引入
fetch探测库:fetch-detector - 引入
fetch的polyfill:fetch-ie8 - 可选:如果你还使用了
jsonp,引入fetch-jsonp - 可选:开启
Babel的runtime模式,现在就使用async/await
Fetch Vs AJAX
- 响应状态为404或5xx,都resolve,但是
ok为false。只有当网络故障或者请求被阻止了,才会reject; - 默认情况不发送不接收cookies,需要设置;
- POST 的数据需要转为JSON;
- 不能设置超时和取消请求,可以通过
Promise.race,了模拟两者; - 文件上传和下载获取不到进度,可使用 response.body 是可读流,具有
getReader,可根据这个来获取下载进度。; - 不能直接获取到响应数据,需要调用响应方法,resolve 一下;
总结
- Fetch API 很底层,使用起来并不丝滑;
- Fetch 错误处理有点复杂;
- Fetch 不支持取消和超时设置;
- 上传和下载进度没有,使用可读流来获取,复杂性突然升高了。
还是使用原生的 xhr 和 axios 库来的爽快。