【发布时间】:2017-07-07 05:06:56
【问题描述】:
在使用 Fetch API(实际上是通过 fetch polyfill)时,我无法让 Safari 从服务器响应中成功应用 Set-Cookie。相同的代码在 FF 和 Chrome 中都能正常工作(我使用原生和 polyfill fetch 进行了测试)。
- 请求是跨域的;
- 是的,我正在设置
credentials: true; - 服务器确实以
Set-Cookie标头响应; - 从 Chrome 和 FF 发送带有 cookie 请求标头的后续请求,但 Safari 没有;
- 请求使用 HTTPS(证书是自签名的,在开发域上,但 Safari 似乎在常规请求中接受);和
有人知道问题可能是什么吗?
我已阅读文档并阅读了许多closed bug reports。除非我错过了什么,否则我认为问题可能出在 'default browser behaviour' 处理 cookie 和 CORS 上——而不是 fetch (阅读 polyfill 源代码,似乎 100% 不了解 cookie)。一些错误报告表明,格式错误的服务器响应可能会阻止保存 cookie。
我的代码如下所示:
function buildFetch(url, init={}) {
let headers = Object.assign({}, init.headers || {}, {'Content-Type': 'application/json'});
let params = Object.assign({}, init, { credentials: 'include', headers });
return fetch(`${baseUrl}${url}`, params);
}
buildFetch('/remote/connect', {method: 'PUT', body: JSON.stringify({ code })})
.then(response => response.json())
.then(/* complete authentication */)
实际的授权请求如下。我正在使用 cURL 来获取确切的请求/响应数据,因为 Safari 很难复制/粘贴它。
curl 'https://mydevserver:8443/api/v1/remote/connect' \
-v \
-XPUT \
-H 'Content-Type: application/json' \
-H 'Referer: http://localhost:3002/' \
-H 'Origin: http://localhost:3002' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8' \
--data-binary '{"token":"value"}'
* Trying 127.0.0.1...
* Connected to mydevserver (127.0.0.1) port 8443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: mydevserver
> PUT /api/v1/remote/connect HTTP/1.1
> Host: mydevserver:8443
> Accept: */*
> Content-Type: application/json
> Referer: http://localhost:3002/
> Origin: http://localhost:3002
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8
> Content-Length: 15
>
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: http://localhost:3002
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Api-Key, Device-Key
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Expose-Headers: Date
< Content-Type: application/json; charset=utf-8
< Content-Length: 37
< Set-Cookie: express:sess=[SESSIONKEY]=; path=/; expires=Fri, 17 Feb 2017 15:30:01 GMT; secure; httponly
< Set-Cookie: express:sess.sig=[SIGNATURE]; path=/; expires=Fri, 17 Feb 2017 15:30:01 GMT; secure; httponly
< Date: Fri, 17 Feb 2017 14:30:01 GMT
< Connection: keep-alive
<
* Connection #0 to host mydevserver left intact
{"some":"normal","response":"payload"}
【问题讨论】:
-
对于 2020 年遇到此问题的任何其他人,请确保您测试 Safari 首选项 → 隐私 → 网站跟踪:防止跨站点跟踪。我不得不把它关掉。 Niklas Merz 的测试应用程序niklas.merz.dev/corstestbugs.webkit.org/show_bug.cgi?id=200857 中详述也有助于确保其他一切正常。
-
启用“防止跨站点跟踪”在我的情况下导致问题。 Safari > 首选项 > 隐私 -> 禁用跨站点跟踪
-
万岁@AmitSaharan
标签: javascript cookies safari fetch cross-domain