浏览器通过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写法的同学可以尝试该方法来解决异步请求问题。