New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

传统 Ajax 已死,Fetch 永生 #2

Open
camsong opened this Issue Sep 30, 2015 · 114 comments

Comments

Projects
None yet
@camsong
Owner

camsong commented Sep 30, 2015

image

原谅我做一次标题党,Ajax 不会死,传统 Ajax 指的是 XMLHttpRequest(XHR),未来现在已被 Fetch 替代。

最近把阿里一个千万级 PV 的数据产品全部由 jQuery 的 $.ajax 迁移到 Fetch,上线一个多月以来运行非常稳定。结果证明,对于 IE8+ 以上浏览器,在生产环境使用 Fetch 是可行的。

由于 Fetch API 是基于 Promise 设计,有必要先学习一下 Promise,推荐阅读 MDN Promise 教程。旧浏览器不支持 Promise,需要使用 polyfill es6-promise

本文不是 Fetch API 科普贴,其实是讲异步处理和 Promise 的。Fetch API 很简单,看文档很快就学会了。推荐 MDN Fetch 教程 和 万能的WHATWG Fetch 规范

Why Fetch

XMLHttpRequest 是一个设计粗糙的 API,不符合关注分离(Separation of Concerns)的原则,配置和调用方式非常混乱,而且基于事件的异步模型写起来也没有现代的 Promise,generator/yield,async/await 友好。

Fetch 的出现就是为了解决 XHR 的问题,拿例子说明:

使用 XHR 发送一个 json 请求一般是这样:

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");
});

使用 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 做准备。

另外,Fetch 也很适合做现在流行的同构应用,有人基于 Fetch 的语法,在 Node 端基于 http 库实现了 node-fetch,又有人封装了用于同构应用的 isomorphic-fetch

注:同构(isomorphic/universal)就是使前后端运行同一套代码的意思,后端一般是指 NodeJS 环境。

总结一下,Fetch 优点主要有:

  1. 语法简洁,更加语义化
  2. 基于标准 Promise 实现,支持 async/await
  3. 同构方便,使用 isomorphic-fetch

Fetch 启用方法

下面是重点↓↓↓

先看一下 Fetch 原生支持率:
image

原生支持率并不高,幸运的是,引入下面这些 polyfill 后可以完美支持 IE8+ :

  1. 由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
  2. 引入 Promise 的 polyfill: es6-promise
  3. 引入 fetch 探测库:fetch-detector
  4. 引入 fetch 的 polyfill: fetch-ie8
  5. 可选:如果你还使用了 jsonp,引入 fetch-jsonp
  6. 可选:开启 Babel 的 runtime 模式,现在就使用 async/await

Fetch polyfill 的基本原理是探测是否存在 window.fetch 方法,如果没有则用 XHR 实现。这也是 github/fetch 的做法,但是有些浏览器(Chrome 45)原生支持 Fetch,但响应中有中文时会乱码,老外又不太关心这种问题,所以我自己才封装了 fetch-detectorfetch-ie8 只在浏览器稳定支持 Fetch 情况下才使用原生 Fetch。这些库现在 每天有几千万个请求都在使用,绝对靠谱

终于,引用了这一堆 polyfill 后,可以愉快地使用 Fetch 了。但要小心,下面有坑:

Fetch 常见坑

  • Fetch 请求默认是不带 cookie 的,需要设置 fetch(url, {credentials: 'include'})
  • 服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。

竟然没有提到 IE,这实在太不科学了,现在来详细说下 IE

IE 使用策略

所有版本的 IE 均不支持原生 Fetch,fetch-ie8 会自动使用 XHR 做 polyfill。但在跨域时有个问题需要处理。

IE8, 9 的 XHR 不支持 CORS 跨域,虽然提供 XDomainRequest,但这个东西就是玩具,不支持传 Cookie!如果接口需要权限验证,还是乖乖地使用 jsonp 吧,推荐使用 fetch-jsonp。如果有问题直接提 issue,我会第一时间解决。

Fetch 和标准 Promise 的不足

由于 Fetch 是典型的异步场景,所以大部分遇到的问题不是 Fetch 的,其实是 Promise 的。ES6 的 Promise 是基于 Promises/A+ 标准,为了保持 简单简洁 ,只提供极简的几个 API。如果你用过一些牛 X 的异步库,如 jQuery(不要笑) 、Q.js 或者 RSVP.js,可能会感觉 Promise 功能太少了。

没有 Deferred

Deferred 可以在创建 Promise 时可以减少一层嵌套,还有就是跨方法使用时很方便。
ECMAScript 11 年就有过 Deferred 提案,但后来没被接受。其实用 Promise 不到十行代码就能实现 Deferred:es6-deferred。现在有了 async/await,generator/yield 后,deferred 就没有使用价值了。

没有获取状态方法:isRejected,isResolved

标准 Promise 没有提供获取当前状态 rejected 或者 resolved 的方法。只允许外部传入成功或失败后的回调。我认为这其实是优点,这是一种声明式的接口,更简单。

缺少其它一些方法:always,progress,finally

always 可以通过在 then 和 catch 里重复调用方法实现。finally 也类似。progress 这种进度通知的功能还没有用过,暂不知道如何替代。

不能中断,没有 abort、terminate、onTimeout 或 cancel 方法

Fetch 和 Promise 一样,一旦发起,不能中断,也不会超时,只能等待被 resolve 或 reject。幸运的是,whatwg 目前正在尝试解决这个问题 whatwg/fetch#27

资料

最后

Fetch 替换 XHR 只是时间问题,现在看到国外很多新的库都默认使用了 Fetch。

最后再做一个大胆预测:由于 async/await 这类新异步语法的出现,第三方的 Promise 类库会逐渐被标准 Promise 替代,使用 polyfill 是现在比较明智的做法。

如果你觉得本文对你有帮助,请点击右上方的 Star 鼓励一下,或者点击 Watch 订阅

@Lucifier129

This comment has been minimized.

Show comment
Hide comment
@Lucifier129

Lucifier129 Sep 30, 2015

不错的文章,赞

Lucifier129 commented Sep 30, 2015

不错的文章,赞

@youngdze

This comment has been minimized.

Show comment
Hide comment
@youngdze

youngdze Sep 30, 2015

谢谢科普!赞赞赞b( ̄▽ ̄)d

youngdze commented Sep 30, 2015

谢谢科普!赞赞赞b( ̄▽ ̄)d

@fanhc019

This comment has been minimized.

Show comment
Hide comment
@fanhc019

fanhc019 Oct 1, 2015

火钳刘明

fanhc019 commented Oct 1, 2015

火钳刘明

@1990lsf

This comment has been minimized.

Show comment
Hide comment
@1990lsf

1990lsf Oct 1, 2015

不错的文章,赞

1990lsf commented Oct 1, 2015

不错的文章,赞

@humanhuang

This comment has been minimized.

Show comment
Hide comment
@humanhuang

humanhuang Oct 9, 2015

Fetch 永生

humanhuang commented Oct 9, 2015

Fetch 永生

@ImHype

This comment has been minimized.

Show comment
Hide comment
@ImHype

ImHype Oct 10, 2015

学到了

ImHype commented Oct 10, 2015

学到了

@liyatang

This comment has been minimized.

Show comment
Hide comment
@liyatang

liyatang commented Oct 11, 2015

学习了

@jnuc093

This comment has been minimized.

Show comment
Hide comment
@jnuc093

jnuc093 Oct 12, 2015

确实有点标题

jnuc093 commented Oct 12, 2015

确实有点标题

@chemzqm

This comment has been minimized.

Show comment
Hide comment
@chemzqm

chemzqm Oct 14, 2015

写的不错,还好我的前端组件跟请求都是分离的

chemzqm commented Oct 14, 2015

写的不错,还好我的前端组件跟请求都是分离的

@ss7247

This comment has been minimized.

Show comment
Hide comment
@ss7247

ss7247 commented Oct 26, 2015

围观

@xiongchen2012

This comment has been minimized.

Show comment
Hide comment
@xiongchen2012

xiongchen2012 Oct 26, 2015

科普的不错。新的项目正在使用~

xiongchen2012 commented Oct 26, 2015

科普的不错。新的项目正在使用~

@Cydmi

This comment has been minimized.

Show comment
Hide comment
@Cydmi

Cydmi Oct 27, 2015

科普下。说不定就用的上

Cydmi commented Oct 27, 2015

科普下。说不定就用的上

@kevin-romens

This comment has been minimized.

Show comment
Hide comment
@kevin-romens

kevin-romens commented Oct 27, 2015

顶下

@shanelau

This comment has been minimized.

Show comment
Hide comment
@shanelau

shanelau Oct 27, 2015

滚粗,标题党。 ajax的promise 写法而已,没有本质差别。 IE11都还要 polyfill的支持, 产品环境用起来也太麻烦

shanelau commented Oct 27, 2015

滚粗,标题党。 ajax的promise 写法而已,没有本质差别。 IE11都还要 polyfill的支持, 产品环境用起来也太麻烦

@Shany100

This comment has been minimized.

Show comment
Hide comment
@Shany100

Shany100 Oct 28, 2015

另一种选择,值得一看。

Shany100 commented Oct 28, 2015

另一种选择,值得一看。

@kisnows

This comment has been minimized.

Show comment
Hide comment
@kisnows

kisnows Oct 28, 2015

polyfill 用的太多了,生产环境用起来压力太大

kisnows commented Oct 28, 2015

polyfill 用的太多了,生产环境用起来压力太大

@camsong

This comment has been minimized.

Show comment
Hide comment
@camsong

camsong Oct 28, 2015

Owner

@kisnows 个数多而已,代码没多少,我们千万级 PV 产品一直运行稳定

Owner

camsong commented Oct 28, 2015

@kisnows 个数多而已,代码没多少,我们千万级 PV 产品一直运行稳定

@VectorHo

This comment has been minimized.

Show comment
Hide comment
@VectorHo

VectorHo commented Oct 29, 2015

get it

@ralphite

This comment has been minimized.

Show comment
Hide comment
@ralphite

ralphite Oct 30, 2015

let data = response.json(); should be let data = await response.json();

btw, how do i log an issue for an issue? 😄

ralphite commented Oct 30, 2015

let data = response.json(); should be let data = await response.json();

btw, how do i log an issue for an issue? 😄

@camsong

This comment has been minimized.

Show comment
Hide comment
@camsong

camsong Oct 31, 2015

Owner

@ralphite wow, nice catch 🌟
Just add a comment here for issues, i will keep checking 😄

Owner

camsong commented Oct 31, 2015

@ralphite wow, nice catch 🌟
Just add a comment here for issues, i will keep checking 😄

@fifiteen82726

This comment has been minimized.

Show comment
Hide comment
@fifiteen82726

fifiteen82726 Nov 1, 2015

但是看起來並沒有比較簡潔好寫啊?有辦法比較其中的效能嗎

fifiteen82726 commented Nov 1, 2015

但是看起來並沒有比較簡潔好寫啊?有辦法比較其中的效能嗎

@codesboy

This comment has been minimized.

Show comment
Hide comment
@codesboy

codesboy commented Nov 1, 2015

@Negaihoshi

This comment has been minimized.

Show comment
Hide comment
@Negaihoshi

Negaihoshi Nov 2, 2015

@fifiteen82726 搭配 async/await 應該非常簡潔吧?

Negaihoshi commented Nov 2, 2015

@fifiteen82726 搭配 async/await 應該非常簡潔吧?

@gdzgshum

This comment has been minimized.

Show comment
Hide comment
@gdzgshum

gdzgshum Nov 3, 2015

在IE里面 我导入了

<script src="./es5-shim.min.js"></script>
<script src="./es5-sham.min.js"></script>
<script src="./es6-promise.min.js"></script>
<script src="./fetch-detector.js"></script>
<script src="./fetch-ie8.js"></script>

然后在点击按钮 变成下载文件了 (文件里面是后端返回的JSON)

gdzgshum commented Nov 3, 2015

在IE里面 我导入了

<script src="./es5-shim.min.js"></script>
<script src="./es5-sham.min.js"></script>
<script src="./es6-promise.min.js"></script>
<script src="./fetch-detector.js"></script>
<script src="./fetch-ie8.js"></script>

然后在点击按钮 变成下载文件了 (文件里面是后端返回的JSON)

@camsong

This comment has been minimized.

Show comment
Hide comment
@camsong

camsong Nov 3, 2015

Owner

@gdzgshum fetch-ie8 和 fetch-detector 要以 CommonJS 方式引用,要使用 Webpack 来打包。如果想用 ES6 语法,就用 Babel 编译一下

Owner

camsong commented Nov 3, 2015

@gdzgshum fetch-ie8 和 fetch-detector 要以 CommonJS 方式引用,要使用 Webpack 来打包。如果想用 ES6 语法,就用 Babel 编译一下

@zhangbg

This comment has been minimized.

Show comment
Hide comment
@zhangbg

zhangbg commented Nov 26, 2015

mark!!!

@liyatang

This comment has been minimized.

Show comment
Hide comment
@liyatang

liyatang Dec 2, 2015

// 伪代码,其中设置headers的时候在浏览器中看到是小写accept
fetch('url', {
    headers: {
        'Accept': 'application/json'
    }
})

得到
image

有遇到么,怎么解决?

liyatang commented Dec 2, 2015

// 伪代码,其中设置headers的时候在浏览器中看到是小写accept
fetch('url', {
    headers: {
        'Accept': 'application/json'
    }
})

得到
image

有遇到么,怎么解决?

@camsong

This comment has been minimized.

Show comment
Hide comment
@camsong

camsong Dec 3, 2015

Owner

@liyatang 测试了一下 Chrome 会把设置的 headers 全部改成小写,但 Firefox 下不会。可能是 Chrome 的 bug,你可以在这里提个 issue https://crbug.com/

Owner

camsong commented Dec 3, 2015

@liyatang 测试了一下 Chrome 会把设置的 headers 全部改成小写,但 Firefox 下不会。可能是 Chrome 的 bug,你可以在这里提个 issue https://crbug.com/

@liyatang

This comment has been minimized.

Show comment
Hide comment
@liyatang

liyatang Dec 3, 2015

@camsong 看官方的解释说正常,标准如此https://fetch.spec.whatwg.org/#terminology-headers

附上issue 链接

liyatang commented Dec 3, 2015

@camsong 看官方的解释说正常,标准如此https://fetch.spec.whatwg.org/#terminology-headers

附上issue 链接

@camsong

This comment has been minimized.

Show comment
Hide comment
@camsong

camsong Dec 3, 2015

Owner

@liyatang 赞高效率,原来这并不是 bug,我也学习了,顺便再补充一下:

根据 HTTP 规范(RFC 7230,RFC 2616),HTTP header 的 name 是不区分大小写的。
而且根据规范,Fetch 和 XHR's setRequestHeader() 都应该把 header 的 name 转成小写,只是有些浏览器没有转而已。

Owner

camsong commented Dec 3, 2015

@liyatang 赞高效率,原来这并不是 bug,我也学习了,顺便再补充一下:

根据 HTTP 规范(RFC 7230,RFC 2616),HTTP header 的 name 是不区分大小写的。
而且根据规范,Fetch 和 XHR's setRequestHeader() 都应该把 header 的 name 转成小写,只是有些浏览器没有转而已。

@Tomatoo

This comment has been minimized.

Show comment
Hide comment
@Tomatoo

Tomatoo May 1, 2017

其实说语法简洁啊,promise啊之类的,其实并不能说明比起jquery.ajax好在哪里,我觉得好处主要是fetch更加底层,支持的数据格式更多,给我们的api更丰富(response,request还有header对象之类的)。

Tomatoo commented May 1, 2017

其实说语法简洁啊,promise啊之类的,其实并不能说明比起jquery.ajax好在哪里,我觉得好处主要是fetch更加底层,支持的数据格式更多,给我们的api更丰富(response,request还有header对象之类的)。

@Blackgan3

This comment has been minimized.

Show comment
Hide comment
@Blackgan3

Blackgan3 commented May 11, 2017

赞一个

@rockallite

This comment has been minimized.

Show comment
Hide comment
@rockallite

rockallite May 18, 2017

参考 axios #314 讨论。

  • 目前 Fetch 的 API 和主流浏览器实现都不支持 timeout 参数及主动 abort(),而且几年时间过去了也没有更多进展,在可预见的将来也未必有明确的结果。如果你的项目对此有需求,不可能无限期等待,只能寻求第三方的 fork 或自己 monkey-patching。
  • 通过 setTimeout()Promise.reject() 实现的 Fetch 超时控制,后果就是下载过程继续在后台进行,数据全部下载完毕后丢弃。这是对流量、带宽和服务器资源的无端浪费。
  • XMLHttpRequest 支持丰富的事件,包括上传和下载进度。在这方面 Fetch 无解。

rockallite commented May 18, 2017

参考 axios #314 讨论。

  • 目前 Fetch 的 API 和主流浏览器实现都不支持 timeout 参数及主动 abort(),而且几年时间过去了也没有更多进展,在可预见的将来也未必有明确的结果。如果你的项目对此有需求,不可能无限期等待,只能寻求第三方的 fork 或自己 monkey-patching。
  • 通过 setTimeout()Promise.reject() 实现的 Fetch 超时控制,后果就是下载过程继续在后台进行,数据全部下载完毕后丢弃。这是对流量、带宽和服务器资源的无端浪费。
  • XMLHttpRequest 支持丰富的事件,包括上传和下载进度。在这方面 Fetch 无解。
@wuyongdec

This comment has been minimized.

Show comment
Hide comment
@wuyongdec

wuyongdec Jun 9, 2017

用fetch能不能处理附件上传下载呢?

wuyongdec commented Jun 9, 2017

用fetch能不能处理附件上传下载呢?

@comeriven

This comment has been minimized.

Show comment
Hide comment
@comeriven

comeriven Jun 10, 2017

fetch似乎好像不能处理下载,我的下载请求发送成功,并且状态码200了,但是并没有把文件给我下载回来。

comeriven commented Jun 10, 2017

fetch似乎好像不能处理下载,我的下载请求发送成功,并且状态码200了,但是并没有把文件给我下载回来。

This was referenced Jun 26, 2017

@Krocsky

This comment has been minimized.

Show comment
Hide comment
@Krocsky

Krocsky Jul 9, 2017

写的针不错

Krocsky commented Jul 9, 2017

写的针不错

@sirzxj

This comment has been minimized.

Show comment
Hide comment
@sirzxj

sirzxj Aug 23, 2017

对于 IE8+ 以上浏览器,在生产环境使用 Fetch 是可行的
原生支持率并不高,幸运的是,引入下面这些 polyfill 后可以完美支持 IE8+

文章前后有点矛盾吧

sirzxj commented Aug 23, 2017

对于 IE8+ 以上浏览器,在生产环境使用 Fetch 是可行的
原生支持率并不高,幸运的是,引入下面这些 polyfill 后可以完美支持 IE8+

文章前后有点矛盾吧

@camsong

This comment has been minimized.

Show comment
Hide comment
@camsong

camsong Aug 23, 2017

Owner

@sirzxj 上面是文章开头概括性的结论。下面是做法。IE8 原生不支持 Fetch,通过引用 polyfill 后可以完美支持 IE8。所以并不矛盾

Owner

camsong commented Aug 23, 2017

@sirzxj 上面是文章开头概括性的结论。下面是做法。IE8 原生不支持 Fetch,通过引用 polyfill 后可以完美支持 IE8。所以并不矛盾

@ryu2gaku

This comment has been minimized.

Show comment
Hide comment
@ryu2gaku

ryu2gaku commented Sep 16, 2017

可以

@gsm340

This comment has been minimized.

Show comment
Hide comment
@gsm340

gsm340 Sep 19, 2017

小白冒昧的问一下,这种方式比ajax好在哪里,能详细说明一下吗

gsm340 commented Sep 19, 2017

小白冒昧的问一下,这种方式比ajax好在哪里,能详细说明一下吗

@junfangfan

This comment has been minimized.

Show comment
Hide comment
@junfangfan

junfangfan Sep 28, 2017

whatwg-fetch使用catch,老版本ios上会有bug,polyfill可以解决吗?

junfangfan commented Sep 28, 2017

whatwg-fetch使用catch,老版本ios上会有bug,polyfill可以解决吗?

@WangYang-Rex

This comment has been minimized.

Show comment
Hide comment
@WangYang-Rex

WangYang-Rex Nov 5, 2017

拥抱变化,大爱fetch

WangYang-Rex commented Nov 5, 2017

拥抱变化,大爱fetch

@huyansheng3

This comment has been minimized.

Show comment
Hide comment
@huyansheng3

huyansheng3 Nov 6, 2017

进度问题是咋解决?

huyansheng3 commented Nov 6, 2017

进度问题是咋解决?

@13463736868

This comment has been minimized.

Show comment
Hide comment
@13463736868

13463736868 Dec 18, 2017

正在接触fetch.........

13463736868 commented Dec 18, 2017

正在接触fetch.........

@liangklfangl

This comment has been minimized.

Show comment
Hide comment
@liangklfangl

liangklfangl Dec 19, 2017

try {
let response = await fetch(url);
let data = await response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
其中response.json()前面为什么需要添加await?该方法本来就不是异步的,加了和不加应该没有什么不同吧

liangklfangl commented Dec 19, 2017

try {
let response = await fetch(url);
let data = await response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
其中response.json()前面为什么需要添加await?该方法本来就不是异步的,加了和不加应该没有什么不同吧

@GHolk

This comment has been minimized.

Show comment
Hide comment
@GHolk

GHolk Jan 16, 2018

為什麼預言標準 promise 會被第三方類庫取代?
只有提供 .then() 方法,async/await 都能處理啊

GHolk commented Jan 16, 2018

為什麼預言標準 promise 會被第三方類庫取代?
只有提供 .then() 方法,async/await 都能處理啊

@DevilRoshan

This comment has been minimized.

Show comment
Hide comment
@DevilRoshan

DevilRoshan Apr 20, 2018

fetch在google和Firefox发请求时,添加请求头后,Firefox无法正常返回数据。
let headers = new Headers();
headers.set('test','test');
然后将headers与其他参数一起发往服务端。
已知已经在服务端做好处理,且Google可以正常请求,而火狐不能。
这个问题是因为火狐不支持fetch带请求头,还是因为服务端处理不完善?求大佬解答一下。

DevilRoshan commented Apr 20, 2018

fetch在google和Firefox发请求时,添加请求头后,Firefox无法正常返回数据。
let headers = new Headers();
headers.set('test','test');
然后将headers与其他参数一起发往服务端。
已知已经在服务端做好处理,且Google可以正常请求,而火狐不能。
这个问题是因为火狐不支持fetch带请求头,还是因为服务端处理不完善?求大佬解答一下。

@DevilRoshan

This comment has been minimized.

Show comment
Hide comment
@DevilRoshan

DevilRoshan Apr 20, 2018

自己已经解决,原因是因为服务端设置有问题
res.header("Access-Control-Allow-Credentials","true");
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "test");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
服务端必须设置可以接收options请求,且必须声明headers的字段,第一行的设置是不能少的,这是声明运行客户端携带证书式访问。

DevilRoshan commented Apr 20, 2018

自己已经解决,原因是因为服务端设置有问题
res.header("Access-Control-Allow-Credentials","true");
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "test");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
服务端必须设置可以接收options请求,且必须声明headers的字段,第一行的设置是不能少的,这是声明运行客户端携带证书式访问。

@watermountain

This comment has been minimized.

Show comment
Hide comment
@watermountain

watermountain commented Aug 14, 2018

onlooker

@vino24

This comment has been minimized.

Show comment
Hide comment
@vino24

vino24 Aug 21, 2018

@liangklfangl response.json()返回值是 Promise

vino24 commented Aug 21, 2018

@liangklfangl response.json()返回值是 Promise

@1335382915

This comment has been minimized.

Show comment
Hide comment
@1335382915

1335382915 Aug 28, 2018

fetch的出现的的确确解决了“回调地狱”,让代码更加易于维护。但目前不建议用在手机上,“超时重发3次后仍未响应则自动中断请求”是手机开发常见需求,reject中断的是promise的状态,请求其实还在继续发送,实际上这是promise的短板,我在将ajaxpromise封装时就遇到了该问题。期待fetch能有一个好的解决方案,让前端开发更加便利~ 持续关注~

1335382915 commented Aug 28, 2018

fetch的出现的的确确解决了“回调地狱”,让代码更加易于维护。但目前不建议用在手机上,“超时重发3次后仍未响应则自动中断请求”是手机开发常见需求,reject中断的是promise的状态,请求其实还在继续发送,实际上这是promise的短板,我在将ajaxpromise封装时就遇到了该问题。期待fetch能有一个好的解决方案,让前端开发更加便利~ 持续关注~

@MontageD

This comment has been minimized.

Show comment
Hide comment
@MontageD

MontageD Sep 5, 2018

文章大部分提到的概念内容都可以从其他渠道去仔细研究和推敲,谢谢博主

MontageD commented Sep 5, 2018

文章大部分提到的概念内容都可以从其他渠道去仔细研究和推敲,谢谢博主

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment