前端 fetch 通信
本文摘至: please call me HR 随着前端异步的发展,XHR 这种耦合方式的书写不利于前端异步的 Promise 回调. 而且,写起来也是很复杂. fetch API 本来是在 SW(ServiceWorkers) 中提出的,不过,后面觉得好用,就把他挂载到 window 对象下. 这样,在前端的正常通信中,我们也可以直接调用. 但,fetch 毕竟比较新,看一下他的兼容性.
在 PC 端上,就 FF,Opera 和 Chrome 比较 fashion. mobile 的话,基本上是不能用的. 当然,前端一直是个拥抱变化的职业,官方已经有一个现成的 polyfill 可以使用. 这样的话,就没必要过多担心. 每用到一个新的 feature,我们首先得知道他能不能用. Modernizr 这个库做的挺好的. 这里,我们简单的了解一下就 ok 了. let isFetch = window.fetch?true:false; fetch 基本格式可以说,fetch 就是 ajax + Promise. 使用的方式和 jquery 提供的 $.ajax() 差不多. fetch('./api/some.json') .then( function(response) { if (response.status !== 200) { console.log(`返回的响应码${response.status}`); return; } // 获得后台实际返回的内容 response.json().then(function(data) { console.log(data); }); } ) .catch(function(err) { console.log('Fetch Error :-S',err); }); 上面的 demo 很好的参数了,fetch 的几个特点.
then 和 catch 是 promise 自带的两个方法,我这里就不多说了. 我们来看一下,json 是干嘛的. 因为返回回来的数据不仅仅包括后台的返回的 Text 内容,还有一些 Headers. 所以在,then 方法里面返回来的 res 实际上并不是我们在业务中想要的内容. 就和在 XHR 里返回数据是一个道理,我们最终要的是 this.json = function() { return this.text().then(JSON.parse) } fetch 传输格式上面的 demo 是一个 get 方法的请求,当然,除了 get,还有其他的 HTTP Method,PUT,DELETE,POST,PATCH 等. 这里,我们就说一个 POST,其他方法的基本格式还是类似的. fetch("http://www.example.org/submit.php",{ method: "POST",headers: { "Content-Type": "application/x-www-form-urlencoded" },body: "this is a post Msg" }).then(function(res) { if (res.ok) { // doSth } else if (res.status == 401) { // doSth } }); 看起来 fetch 和 $.ajax 并没有多大的区别... Headers 操作Headers 的操作无非就是 CRUD,这里我就不过多赘述,直接看代码吧: var content = "Hello World"; var reqHeaders = new Headers(); reqHeaders.append("Content-Type","text/plain" reqHeaders.append("Content-Length",content.length.toString()); reqHeaders.append("X-Custom-Header","自定义头"); 当然,你也可以使用字面量的形式: reqHeaders = new Headers({ "Content-Type": "text/plain","Content-Length": content.length.toString(),"X-Custom-Header": "自定义头",}); 接下来就是,头部的内容的检测相关. 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","新增自定义头"); console.log(reqHeaders.get("Content-Length")); // 11 console.log(reqHeaders.getAll("X-Custom-Header")); // ["自定义头","新增自定义头"] reqHeaders.delete("X-Custom-Header"); console.log(reqHeaders.getAll("X-Custom-Header")); // [] 不过,鉴于安全性的考虑,有时候在多人协作或者子版块管理时,对于头部的限制还是需要的. 这里,我们可以通过
对比与 fetch,我们没有办法去设置 Headers的 guard,所以,这只能在 SW 里使用. Request 操作Request 的基本用法和 fetch 差不多. var uploadReq = new Request("/uploadImage",headers: { "Content-Type": "image/png",},body: "image data" }); fetch("/uploadImage",body: "image data" }); 在浏览器里,一切请求都逃不过跨域和不跨域的问题. fetch 也是. 对于跨域的请求,主要的影响还是体现在 Response 中,这 fetch Request 这,没多大影响. 不过,我们需要在 fetch 设置 fetch('https://www.villainhr.com/cors-enabled/some.json',{mode: 'cors'}) .then(function(response) { return response.text(); }) 常用的 mode 属性值有:
另外,还有一个关于 cookie 的跨域内容. 在 XHR2 中,我们了解到,withCredentials 这个属性就是用来设置在进行跨域操作时,对不同域的 Server 是否发送本域的 cookie. 一般设置为 omit(不发送). 在 fetch 当中,使用的是
所以,如果你想发送 ajax 时,带上 cookie,那么你就需要使用 same-origin,如果想在跨域时也带上 cookie,那么就需要 include. // 跨域请求 fetch('https://www.villainhr.com/cors-enabled/some.json',{mode: 'cors',credentials:'include'}) .then(function(response) { return response.text(); }) Response 操作response 应该算和 fetch 最为接近的一个对象. Response 的实际其实就是 fetch 回调函数传回的参数. Response 中比较常用的属性有四个: status,statusText,ok,type.
fetch('https://www.villainhr.com/cors-enabled/some.json',credentials:'include'}) .then(function(response) { // ... }) 这里,我们主要关心一下 type 上面挂载的一些属性.
另外,在 response 上面,还挂载了几个常用的方法: text(),json().
使用方式都是流式 API. fetch('https://www.villainhr.com/cors-enabled/some.json') .then(function(res) { res.text().then((text)=>{...}) res.json().then((obj)=>{...}) }) 基本的内容就是上述内容. 如果想更详细参考的话,请查阅: This API is so Fetching! introduction-to-fetch (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |