浏览器通过XMLHttpRequest(XHR)来实现异步请求,但是这种方式存在如下问题:
基于以上原因,出现了 fetch api ,也经常跟service worker一起搭配使用。fetch api下存在Headers、Request、Response三个类,直接与HTTP的相关定义对应起来,异步操作变得更加灵活、强大。
通过Headers,可以方便地对request、response的Headers信息进行增、删、改、查的操作:
还有就是查询的某些接口返回的是iterator,这样就可以使用for…of进行遍历:
const header = new Headers; header.append('content-type', 'application'); header.append('connection', 'keep-alive'); for (let item of header.entries()) { console.log(item) } // ["content-type", "application"] // ["connection", "keep-alive"] // 上述代码可以直接写成 for (let item of header) { console.log(item) } 其中因为安全因素, Headers有些属性是不可写的,header对象中存在一个不对外的属性 guard ,规定了不同情况( none / request / request-no-cors / response / immutable )下Headers的行为。
无论Request还是Response,里面均存在 body 属性,该属性存储请求的内容,由于javascript里面数据类型的复杂性: ArrayBuffer 、 Blob 、 string 、 URLSearchParam 、 FormData ,所以fetch提供了mixin类 Body ,用于处理不同类型的数据。
Body除了具有相关数据类型的处理方法外,还有一个字段 bodyUsed ,用于标示该 body 是否已经被读取。因为 body 是stream,只能被读取一次。
那么如何要多次读取 body 里面的内容,就需要首先进行 clone 。
Request定义了HTTP请求获取资源的request格式,接受两个参数: url 、 options ,实际中往往不需要手动new一个request对象,通过其他操作会返回一个request对象:
const req = new Request('http://example.com/api/data', { method: 'POST', headers: { 'content-type': 'application/json', }, body: 'name=test&age=12', mode: 'cors', credentials: 'include', }); console.log('request body is readed ? : ',req.bodyUsed); req.json().then((json) => { console.log(json); console.log('request body is readed ? : ',req.bodyUsed); }).catch((err) => { console.log(err) }); // request body is readed ? : false // demo:13 Object {name: "test", count: 123} // request body is readed ? : true 相对于XHR方式,Request对象可以很方便、明确地显示是否允许跨域(mode)、是否需要携带cookie(credentials)等。
Response对应http的相应,里面包含了服务相应的相关信息,除了在service worker中,是不需要显示创建。
fetch('/api/data').then((res) => { console.log('res headers: ', res); return res.json(); }).then((json) => { console.log('json2 is: ', json); }).catch((err) => { console.log('the error is: ', err); }) Response里面存在如下属性来描述HTTP相应的结果:
status=2** 时, ok === true basic 、 cors 、 error 、 opaque ,指明该HTTP请求是否跨域、错误等信息 在github上已经出现了fetch的 polyfill ,并且非常流行,厌倦XHR写法的同学可以尝试该方法来解决异步请求问题。