最近在研究React这个框架,成功的成为了一名新的入坑着。用过React的都知道React的强大主要是在于它的生态的强大,React说的再大不过也就是一个UI框架罢了。不过咱们学习react也主要由于这个生态,有facebook支持,质量相对有保障,衍生出的react-native, react-canvas等轮子在不少场景下能够直接拿来用。碎片化是React当前的状态,好比flux库,promise库,utils函数库,dom操做库,ajax库等等,每一个点都有2-3个库在开源社区处于竞争状态,各有所长,你们根据自身的须要去选择。而我打算用Fetch做为ajax库来摆脱jquery这个千年不变的大杀器。前端
咱们一提到局部刷新,先后端交互,异步加载等首先想到的ajax,好像在咱们的认知中除了ajax就没有别的了。其实咱们都被这种观念误导了,ajax只是对于XMLHttpRequest的一种封装,咱们谈及Ajax技术的时候,一般意思就是基于XMLHttpRequest的Ajax,它是一种可以有效改进页面通讯的技术。而Fetch API则是XMLHttpRequest的最新替代技术, 它是W3C的正式标准。react
下面咱们看一下Fetch的兼容性jquery
整体来讲,最新的浏览器都开始慢慢的兼容它了,可是想让它独立的用于前端项目仍是任重而道远啊。。。git
若是你想独立在前端项目中兼容Fetch,能够考虑看这篇文章使用fetch遇到过的坑可是我不推荐去本身部署Fetch。github
我是在React项目中了解到Fetch的,使用的包是:whatwg-fetchweb
前面说了那么多,身为吃瓜群众的咱们就是好奇:那他有什么优势能让颠覆了整个前端行业的ajax退位让贤呢?ajax
XMLHttpRequest 是一个设计粗糙的 API,不符合关注分离(Separation of Concerns)的原则,配置和调用方式很是混乱,并且基于事件的异步模型写起来也没有现代的 Promise,generator/yield,async/await 友好。npm
Fetch 的出现就是为了解决 XHR 的问题,拿例子说明:json
使用 XHR 发送一个 json 请求通常是这样:canvas
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 后,顿时看起来好一点(其实jquery的ajax也实现了Promise)
fetch(url).then(function(response) { return response.json(); }).then(function(data) { console.log(data); }).catch(function(e) { console.log("Oops, error"); });
使用 ES6 的 箭头函数 后:
fetch(url).then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e))
如今看起来好不少了,但这种 Promise 的写法仍是有 Callback 的影子,并且 promise 使用 catch 方法来进行错误处理的方式有点奇怪。不用急,下面使用 async/await 来作最终优化:
注:async/await 是很是新的 API,属于 ES7,目前尚在 Stage 1(提议) 阶段,这是它的完整规范。使用 Babel 开启 runtime 模式后能够把 async/await 无痛编译成 ES5 代码。也能够直接使用 regenerator 来编译到 ES5。
try { let response = await fetch(url); let data = await response.json(); console.log(data); } catch(e) { console.log("Oops, error", e); } // 注:这段代码若是想运行,外面须要包一个 async function
duang~ 的一声,使用 await 后,写异步代码就像写同步代码同样爽。await 后面能够跟 Promise 对象,表示等待 Promise resolve() 才会继续向下执行,若是 Promise 被 reject() 或抛出异常则会被外面的 try...catch 捕获。
Promise,generator/yield,await/async 都是如今和将来 JS 解决异步的标准作法,能够完美搭配使用。这也是使用标准 Promise 一大好处。最近也把项目中使用第三方 Promise 库的代码所有转成标准 Promise,为之后全面
使用 async/await 作准备。
以上资料来自 传统 Ajax 已死,Fetch 永生
可是我认为Fetch最不一样于ajax的是让咱们对于请求头的设置更加方便,更加灵活。
对于传统的XMLHttpRequest而言,你必须使用它的一个实例来执行请求和检索返回的响应。 可是经过Fetch API,咱们还可以明确的配置请求对象。你能够经过Request构造器函数建立一个新的请求对象,这也是建议标准的一部分。 第一个参数是请求的URL,第二个参数是一个选项对象,用于配置请求。请求对象一旦建立了, 你即可以将所建立 的对象传递给fetch()方法,用于替代默认的URL字符串。示例代码以下:
var req = new Request(URL, {method: 'GET', cache: 'reload'}); fetch(req).then(function(response) { return response.json(); }).then(function(json) { insertPhotos(json); });
上面的代码中咱们指明了请求使用的方法为GET,而且指定不缓存响应的结果。
有关Request对象的另外一件更酷的事在于,你还能够基于原有的对象建立一个新的对象。 新的请求和旧的并无什么不一样,但你能够经过稍微调整配置对象,将其用于不一样的场景。 例如,你能够基于原有的GET请求建立一个POST请求,它们具备相同的请求源。代码以下:
// 基于req对象建立新的postReq对象 var postReq = new Request(req, {method: 'POST'});
每一个Request对象都有一个header属性,在Fetch API中它对应了一个Headers对象。 经过Headers对象,你可以修改请求头。不只如此,对于返回的响应,你还能轻松的返回响应头中的各个属性。 可是须要注意的是,响应头是只读的。
var headers = new Headers(); headers.append('Accept', 'application/json'); var request = new Request(URL, {headers: headers}); fetch(request).then(function(response) { console.log(response.headers); });
在上面的代码中,你能够经过Headers构造器来获取这个对象,用于为新的Request对象配置请求头。
类似的,你能够建立一个Response对象:
function responseDemo() { var headers = new Headers({ 'Content-Type': 'application/json', 'Cache-Control': 'max-age=3600' }); var response = new Response( JSON.stringify({photos: {photo: []}}), {status: 200, headers: headers} ); response.json().then(function(json) { insertPhotos(json); }); }
Request和Response都彻底遵循HTTP标准。
以上资料来自 深刻浅出Fetch API
其实整合这篇文章毛目的没有,就是由于注意用post提交数据时记得设置'Content-Type'为'application/x-www-form-urlencoded; charset=UTF-8'