浏览器Cookie覆盖行为与RFC规范不一致的原因探究
我为明确浏览器覆盖已有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
相关产品推荐
相关产品推荐

