fetch接口是用来解决Ajax(xhr)在写法和调用上的不合理和开放的js接口,已经在很多项目上使用,运行良好,取代ajax也只是时间问题,虽然fetch还有一些功能不全面但是使用上已经没有什么问题,所以我写下来记录一下自己的学习
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = function() {
console.log(xhr.response);
};
xhr.onerror = function() {
console.log("Oops, error");
};
xhr.send();
fetch请求
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
从上面就可以看出来ajax请求将各个方法都分开写,不直观用起来也很麻烦,还需要写一些兼容性的代码,同时对ajax的封装可能会用到回调函数。fetch方法更为简单,基本和promise的用法相同,流程是线性的,且不用考虑回调问题。
fetch已经兼容大部分浏览器,ie8以上需要使用polyfill做兼容,ie8以下的版本就别考虑了。fetch接口以及在很多的项目上使用,国外的项目使用fetch以及成为一个惯例,国内阿里也将fetch用在很多项目上,使用上没有任何问题,ant design pro上的请求方法也是在对fetch的封装(ps:上一篇博客,有写我怎么修改原来封装的request函数),所以开始使用fetch吧,已经没有什么好顾虑的了。
现来一个完整的fetch,每个属性干嘛用的一些先简单写在注释里
fetch('http://www.demo.com/demo',
//下面是http请求的配置项,根据自己的实际接口来写
{
body: JSON.stringify(data), // 发送的数据
cache: 'no-cache', // 设置 cache 模式 *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // 是否需要包含cookie include(包含), same-origin(同源), omit(不包含|默认) 因为默认是不包含的 所以如果你要发送cookie加必须写include
//请求头,可以用 Header对象的实例来设置
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // 请求方式,GET, POST, PUT, DELETE, etc.
mode: 'cors', //是否cors跨域 no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
}
)
.then(function(response) {
//response并不是直接的返回数据,而是一个Response对象的实例,要获取数据用json(),下面会介绍
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
看起来是不是很简单 ,上面的一个例子就把fetch的使用说清楚了,但是要完全使用还要需要了解Headers对象和Response对象,下面介绍这两个
Headers就是为了设置header属性的,相较于上面的直接写一个对象的方式,Headers可以使用guard
属性控制Header是否可读,可修改等。现来看下Headers怎么用:
通过append添加元素
var headers = new Headers();
reqHeaders.append("Content-Type", "text/plain"
reqHeaders.append("X-Custom-Header", "ProcessThisImmediately");
直接传入构造函数
`reqHeaders = new Headers({ "Content-Type": "text/plain", "Content-Length": content.length.toString(), "X-Custom-Header": "ProcessThisImmediately",});`
修改对象
console.log(reqHeaders.has("Content-Type")); // true
console.log(reqHeaders.has("Set-Cookie")); // false
reqHeaders.set("Content-Type", "text/html");
reqHeaders.append("X-Custom-Header", "AnotherValue");
console.log(reqHeaders.get("Content-Length")); // 11
console.log(reqHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
reqHeaders.delete("X-Custom-Header");
console.log(reqHeaders.getAll("X-Custom-Header")); // []
然后介绍一下Headers存在最主要的意义就是有一个guard
属性,控制Header对象是否可以被操作,有以下值
"none"
:默认值"request"
:Request.headers
对象只读"request-no-cors"
:在 no-cors
模式下,Request.headers
对象只读"response"
:Response.headers
对象只读"immutable"
:通常在 ServiceWorkers 中使用,所有 Header 对象都为只读之前就说过了,fetch的then中返回的不是一个字面量对象,而是一个Response对象的实例,返回的实例可用以下方法,分别处理数据
arrayBuffer()
获取ArrayBuffer格式的promise对象blob()
获取Bolb格式的promise对象json()
-获取字符串对象text()
获取json的promise对象formData()
获取formData格式的promise对象还有主要的属性(其他属性自己看)
Response文档
Response.status
包含Response的状态码 (例如, 200 成功
).,网络的状态码
Response.ok
包含了一个布尔值来标示该Response成功(状态码200-299) 还是失败.
Response.url
包含Response的URL.
其他基本上就没什么了,基本上看完就能直接用了,fetch的api本身就很简单,形式也和promise一样,所以也很习惯使用,唯一还有不足的就是没用abort
,cancel
等方法可以中断请求,也没有isRejected
,isResolved
方法可以获取状态,也没finally
,always
等方法,但是对于普通的使用不没有大影响,日后fetch也会进一步完善。对于fetch的使用也需要进一步封装,最好是封装成async
函数的方式,异步流程更好控制,这些在一些现成的框架上也有写好的方法可以学习一下,链接在下面