runtime error c++怎么解决_fetch的常见问题及其解决办法

引言

说到fetch就不得不提XMLHttpRequest了,XHR在发送web请求时需要开发者配置相关请求信息和成功后的回调,尽管开发者只关心请求成功后的业务处理,但是也要配置其他繁琐内容,导致配置和调用比较混乱,也不符合关注分离的原则;fetch的出现正是为了解决XHR存在的这些问题。例如下面代码:

fetch(url) .then(function(response) { return response.json(); }) .then(function(data) { console.log(data); }) .catch(function(e) { console.log("Oops, error"); });

上面这段代码让开发者只关注请求成功后的业务逻辑处理,其他的不用关心,相当简单;也比较符合现代Promise形式,比较友好。

fetch是基于Promise设计的,从上面代码也能看得出来,这就要求fetch要配合Promise一起使用。正是这种设计,fetch所带来的优点正如传统 Ajax 已死,Fetch 永生总结的一样:

  • 语法简单,更加语义化
  • 基于标准的Promise实现,支持async/await
  • 使用isomorphic-fetch可以方便同构

不过话说回来,fetch虽然有很多优点,但是使用fetch来进行项目开发时,也是有一些常见问题的,下面就来说说fetch使用的常见问题。

fetch兼容性

fetch是相对较新的技术,当然就会存在浏览器兼容性的问题,借用上面应用文章的一幅图加以说明fetch在各种浏览器的原生支持情况:

c029afe0051fd7711ee27ffeeea65e6b.png

从上图可以看出,在各个浏览器低版本的情况下都是不被支持的。

那么问题来了,如何在所有浏览器中通用fetch呢,当然就要考虑fetch的polyfill了。

上面说过,fetch是基于Promise来实现的,所以在低版本浏览器中Promise可能也未被原生支持,所以还需要Promise的polyfill;大多数情况下,实现fetch的polyfill需要涉及到的:

  • promise的polyfill,例如es6-promise、babel-polyfill提供的promise实现。
  • fetch的polyfill实现,例如isomorphic-fetch和whatwg-fetch

这样是否就可以安全的使用fetch来进行前后端通信了?上面说了在大多数情况下是这样,但是IE8/9则比较特殊:IE8它使用的是ES3,而IE9则对ES5部分支持。这种情况下还需要ES5的polyfill es5-shim支持了。

上述有关promise的polyfill实现,需要说明的是:

babel-runtime是不能作为Promise的polyfill的实现的,否则在IE8/9下使用fetch会报Promise未定义。为什么?我想大家猜到了,因为babel-runtime实现的polyfill是局部实现而不是全局实现,fetch底层实现用到Promise就是从全局中去取的,拿不到这报上述错误。

另外,顺便补充一下fetch的polyfill实现思路是:

首先判断浏览器是否原生支持fetch,否则结合Promise使用XMLHttpRequest的方式来实现;这正是whatwg-fetch的实现思路,而同构应用中使用的isomorphic-fetch,其客户端fetch的实现是直接require whatwg-fetch来实现的。

fetch默认不携带cookie

fetch发送请求默认是不发送cookie的,不管是同域还是跨域;那么问题就来了,对于那些需要权限验证的请求就可能无法正常获取数据,这时可以配置其credentials项,其有3个值:

  • omit: 默认值,忽略cookie的发送
  • same-origin: 表示cookie只能同域发送,不能跨域发送
  • include: cookie既可以同域发送,也可以跨域发送

credentials所表达的含义,其实与XHR2中的withCredentials属性类似,表示请求是否携带cookie。

这样,若要fetch请求携带cookie信息,只需设置一下credentials选项即可,例如fetch(url, {credentials: 'include'});

另外补充一点:

fetch默认对服务端通过Set-Cookie头设置的cookie也会忽略,若想选择接受来自服务端的cookie信息,也必须要配置credentials选项;

fetch请求对某些错误http状态不会reject

这主要是由fetch返回promise导致的,因为fetch返回的promise在某些错误的http状态下如400、500等不会reject,相反它会被resolve;只有网络错误会导致请求不能完成时,fetch 才会被 reject;所以一般会对fetch请求做一层封装,例如下面代码所示:

function checkStatus(response) { if (response.status >= 200 && response.status < 300) { return response; } const error = new Error(response.statusText); error.response = response; throw error;}function parseJSON(response) { return response.json();}export default function request(url, options) { let opt = options || {}; return fetch(url, { credentials: "include
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值