Dar*_*eal 8 javascript cookies fetch response-headers fetch-api
您可能知道,RFC 6265表明允许有多个带有该Set-Cookie
名称的标头。
然而,提取API不允许这样做,因为所有的暴露的方法头接口(包括get()
,set()
,append()
,entries()
和所有其余的)已实施的所有具有相同名称的头的值合并成一个头分离用逗号。
例如,如果我们这样做:
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');
Run Code Online (Sandbox Code Playgroud)
然后我们尝试使用 读取set-cookie
值get('set-cookie')
,或者通过headers
使用迭代变量entries()
,我们得到:
'set-cookie' : test1=v; Max-Age=0, test2=v; Max-Age=0, test3=v; Max-Age=0
Run Code Online (Sandbox Code Playgroud)
请注意,如果我们尝试读取或操作具有多个同名标头的现有响应对象(即由可以说支持此类允许行为的其他框架创建),也会发生相同的错误行为:换句话说,似乎Fetch API
是完全无法妥善处理这种情况。
现在,虽然这种行为所需的一些报头,如Accept
,该Set-Cookie
标题不正确地被大多数浏览器(包括铬和Firefox)解析,从而导致不正确设置的cookie。
这是一个已知的错误吗?如果是这种情况,是否有可用的解决方法来克服这个问题?
这是标准的一个已知“问题”。其实是小节中Fetch API标准的第一个注解Headers
:
与
header
列表不同,一个Headers
对象不能表示多个Set-Cookie
标题。在某种程度上,这是有问题的,因为与所有其他标Set-Cookie
头不同,标头无法组合,但由于Set-Cookie
标头不会暴露给客户端 JavaScript,因此这被认为是可以接受的折衷方案。实现可以选择更有效的 Headers 对象表示,即使对于标题列表,只要它们还支持Set-Cookie
标题的关联数据结构。
您可以在规范的 repo 中阅读更多内容,甚至提出您自己的问题。
不过,已经有几个问题在详细讨论Set-Cookie
此案:
您提到使用变通方法,但这实际上取决于您的用例。
该注释提到使用二级结构来处理这些。
如果您真的想将这些 cookie 存储在一个Headers
对象中,您可以添加自定义标头来存储它们:
new Headers([
['X-MyOwn-Set-Cookie-1', 'cookie1=value1'],
['X-MyOwn-Set-Cookie-2', 'cookie2=value2']
]);
Run Code Online (Sandbox Code Playgroud)
显然,这不是标准可接受的解决方案,但也许您的实际考虑可能符合这种妥协。
正如本说明和评论中的@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/`));
Run Code Online (Sandbox Code Playgroud)
1号航站楼
$ node test.js
Listening on http://localhost:3000/
Run Code Online (Sandbox Code Playgroud)
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
[...]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3491 次 |
最近记录: |