You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器Cookie覆盖行为与RFC规范不一致的原因探究

浏览器Cookie覆盖行为与RFC6265规范的差异疑问

我为明确浏览器覆盖已有Cookie的具体条件,查阅了RFC6265规范中#storage-model第11步的伪代码,按规范理解,Domain属性为空的Cookie应与指定Domain的Cookie视为不同。但在Chrome和Firefox中实验发现并非如此——仅当Path属性非空且不为/时,浏览器才会将Cookie视为不同。

实验所用Express代码

(直接设置Set-Cookie头,无库特定行为)

import express from "express";

const app = express()

app.get("/",(req,res)=>{
    res.send("front page");
});

const inspect = function(req,res){
    res.send(req.headers.cookie);
};

app.get("/inspect",inspect);
app.get("/subdir/inspect",inspect);

app.get("/bar1",(req,res)=>{
    res.append("Set-Cookie", "foo=bar1;")
    res.send("set foo to bar1");
});

app.get("/bar2",(req,res)=>{
    res.append("Set-Cookie", "foo=bar2;")
    res.send("set foo to bar2");
});

app.get("/bar3",(req,res)=>{
    res.append("Set-Cookie", "foo=bar3; Domain=localhost; Path=/;");
    res.send("set foo to bar3 with attrs");
});

//bar1, bar2, and bar3 gets treated the same

app.get("/bar4",(req,res)=>{
    res.append("Set-Cookie", "foo=bar4; Domain=localhost; Path=/subdir;");
    res.send("set foo to bar4 with path /subdir");
});

//bar4 gets treated differently as expected

app.get("/clear",(req,res)=>{
    res.append("Set-Cookie", "foo=bar1; expires=Thu, Jan 01 1970 00:00:00 UTC;");
    res.append("Set-Cookie", "foo=bar2; expires=Thu, Jan 01 1970 00:00:00 UTC;");
    res.append("Set-Cookie", "foo=bar3; Domain=localhost; Path=/; expires=Thu, Jan 01 1970 00:00:00 UTC;");
    res.append("Set-Cookie", "foo=bar4; Domain=localhost; Path=/subdir; expires=Thu, Jan 01 1970 00:00:00 UTC;");
    res.send("cleared all cookies");
});

app.listen(3020);

实验执行步骤

在localhost:3020/控制台执行以下代码:

console.log(await (await fetch("/clear")).text());
console.log(await (await fetch("/bar1")).text());
console.log(await (await fetch("/subdir/inspect")).text());
console.log(await (await fetch("/bar2")).text());
console.log(await (await fetch("/subdir/inspect")).text());
console.log(await (await fetch("/bar3")).text());
console.log(await (await fetch("/subdir/inspect")).text());
console.log(await (await fetch("/bar4")).text());
console.log(await (await fetch("/subdir/inspect")).text());

控制台输出

cleared all cookies
set foo to bar1
foo=bar1
set foo to bar2
foo=bar2
set foo to bar3 with attrs
foo=bar3
set foo to bar4 with path /subdir
foo=bar4; foo=bar3

疑问

  • 为何会出现这种与RFC规范不符的行为?
  • 该行为是否仅针对localhost环境?
  • 这种浏览器行为的可靠性如何?

补充说明

我发现空值或无效的Path字段会被设为/,这解答了Path相关的疑问,具体算法见上述RFC文档的5.1.4节。


内容的提问来源于stack exchange,提问作者martian17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:32:21