您可能知道,RFC 6265 表示允许有多个名称为 Set-Cookie
的 header 。
但是, Fetch API 不允许这样做,因为它的 Headers 接口(interface)公开的所有方法(包括 get()
、 set()
、 append()
、 entries()
和所有其他方法)都已实现将所有具有相同名称的 header 的值合并到一个用逗号分隔的单个标题。
例如,如果我们这样做:
var headers = new Headers();
headers.append('content-type', 'text/plain');
headers.append('set-cookie', 'test1=v; Max-Age=0');
headers.append('set-cookie', 'test2=v; Max-Age=0');
headers.append('set-cookie', 'test3=v; Max-Age=0');
然后我们尝试使用 set-cookie
读取 get('set-cookie')
值,或者通过使用 headers
迭代 entries()
变量,我们得到:'set-cookie' : test1=v; Max-Age=0, test2=v; Max-Age=0, test3=v; Max-Age=0
请注意,如果我们尝试读取或操作具有多个同名 header 的现有响应对象(即由可以支持此类允许行为的其他框架创建)的现有响应对象,也会发生相同的错误行为:换句话说,它看起来像 Fetch API
完全无法妥善处理这种情况。现在,虽然某些 header 需要这种行为,例如
Accept
,但大多数浏览器(包括 Chrome 和 Firefox)都无法正确解析 Set-Cookie
header ,从而导致未正确设置 cookie。这是一个已知的错误吗?如果是这种情况,是否有可用的解决方法可以用来克服这个问题?
最佳答案
这是该标准的一个已知“问题”。它实际上是 Fetch API standard 的第一个音符在 Headers
部分:
Unlike a
header
list, aHeaders
object cannot represent more than oneSet-Cookie
header. In a way this is problematic as unlike all other headersSet-Cookie
headers cannot be combined, but sinceSet-Cookie
headers are not exposed to client-side JavaScript this is deemed an acceptable compromise. Implementations could chose the more efficient Headers object representation even for a header list, as long as they also support an associated data structure forSet-Cookie
headers.
您可以阅读更多内容,甚至可以在 spec's repo 中提出您自己的问题。 .
已经有一些问题在讨论
Set-Cookie
详细的案例:您提到了使用变通方法,但这实际上取决于您的用例。
该说明提到使用二级结构来处理这些。
如果您真的想将这些 cookie 存储在
Headers
对象,您可以添加自定义 header 来存储它们:new Headers([
['X-MyOwn-Set-Cookie-1', 'cookie1=value1'],
['X-MyOwn-Set-Cookie-2', 'cookie2=value2']
]);
显然,这不是标准的可接受解决方案,但也许您的实际考虑可能符合这种折衷方案。正如本注释和评论中的@Barmar 所指出的,您通常使用
Set-Cookie
从服务器,而不是前端。例如设置多个
Set-Cookie
没有问题与 express
:测试.js
const express = require('express');
const app = express();
const cookies = [
{ key: 'cookie1', value: 'value1' },
{ key: 'cookie2', value: 'value2' },
];
app.get('*', (req, res) => {
console.log(req.url);
for (const { key, value } of cookies) {
res.cookie(key, value, { expires: new Date(Date.now() + 1000 * 60), httpOnly: true });
}
res.status(200).send('Success');
});
app.listen(3000, () => console.log(`Listening on http://localhost:3000/`));
1号航站楼$ node test.js
Listening on http://localhost:3000/
2号航站楼$ curl -v http://localhost:3000/
[...]
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Set-Cookie: cookie1=value1; Path=/; Expires=Tue, 04 Aug 2020 19:45:53 GMT; HttpOnly
< Set-Cookie: cookie2=value2; Path=/; Expires=Tue, 04 Aug 2020 19:45:53 GMT; HttpOnly
< Content-Type: text/html; charset=utf-8
[...]
关于javascript - 如何使用 Fetch API 获取/设置多个 'Set-Cookie' header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63204093/