为何设置credentials:'include'时,SameSite=Lax Cookie会随跨域POST XHR发送?
问题
我查阅资料得知,SameSite=Lax 的Cookie不应随跨域POST XHR请求发送,于是尝试复现该行为:
- 前端部署在8080端口,代码如下:
<button onclick="callPostApiCrossSite()">Call POST CrossSite</button> <script> const crossSiteUrl = "http://localhost:8081" const optionsForPost = { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, } var x = fetch(`${crossSiteUrl}/crossSite`, optionsForPost) console.log(x); </script>
- 后端部署在8081端口,代码如下:
http.createServer(function (request, response) { try { // log the request on console console.log(request.url); // Dispatch dispatcher1.dispatch(request, response); } catch (err) { console.log(err); } }).listen(8081); dispatcher1.on("options", "/crossSite", function(request, response) { console.log("option is called"); response.writeHeader(200, { "Access-Control-Allow-Credentials": "true", "Access-Control-Allow-Methods": "GET,POST" , "Access-Control-Allow-Headers": "content-type", "Access-Control-Allow-Origin": "http://localhost:8080", }); response.end(); }) dispatcher1.onPost("/crossSite", function (request, response) { console.log("8081 Post Cookie: ", request.headers["cookie"]) response.writeHeader(200, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "http://localhost:8080", "Access-Control-Allow-Credentials": "true", }); response.write('{"Statue": "OK"}') response.end(); });
浏览器中存在SameSite=Lax的Cookie,我从8080前端发起跨域POST请求到8081,结果浏览器未抛出CORS错误,后端成功接收到Cookie。请问这是否为预期行为,能否解释原因?
解答
这是预期行为,核心原因如下:
1. SameSite=Lax的限制针对「跨站」而非「跨域」
浏览器判断是否限制Cookie发送,关键是区分「同一站点(same-site)」和「跨站(cross-site)」,而非简单的跨域(不同origin):
- 同一站点的判定依据是eTLD+1相同,
localhost:8080和localhost:8081的eTLD+1都是localhost,属于同一站点范畴; SameSite=Lax的规则仅会阻止跨站场景下的非顶级导航请求(比如脚本发起的XHR/fetch)携带Cookie,同一站点内的跨域请求(哪怕端口不同)不受此限制,Cookie会正常发送。
2. CORS配置合规,无错误符合预期
你的后端已经正确配置了CORS相关响应头:
- 指定了
Access-Control-Allow-Origin为前端的具体域名http://localhost:8080; - 设置
Access-Control-Allow-Credentials: true,明确允许请求携带凭证(Cookie); - 预检OPTIONS请求也返回了允许的请求方法、头信息。
这些配置完全符合浏览器的CORS规则,所以不会触发CORS错误,请求能顺利完成。
如果想要复现SameSite=Lax阻止Cookie发送的场景,需要将前后端部署在不同站点,比如前端用localhost:8080,后端用test.com:8081(可通过修改本地hosts文件模拟),这时跨站的POST XHR请求就不会携带SameSite=Lax的Cookie了。
内容的提问来源于stack exchange,提问作者Mohit Kumar
相关产品推荐
相关产品推荐

