Cookie主域名与子域名共享的核心答案只有一句话:通过设置Cookie的Domain属性为顶级域名(如.example.com),并在服务端正确配置SameSite与Secure属性,即可让主域名和所有子域名自动携带同一份Cookie。
Cookie跨域共享的核心原理
Domain属性决定Cookie的归属范围
浏览器在接收Set-Cookie响应头时,会读取两个关键参数:Domain和Path,其中Domain规定了Cookie可以被发送到哪些域名,当服务端返回Set-Cookie: session_id=abc; Domain=.example.com时,浏览器会把这个Cookie视为example.com及其所有子域名共享的数据。
默认情况下,如果不显式设置Domain属性,Cookie的归属范围是当前请求的完整主机名,且不包含子域名,例如在www.example.com页面设置Cookie,则该Cookie只能被www.example.com自身读取,api.example.com和example.com都无法获得。
共享的关键操作就是:让Cookie的Domain值以点开头,后跟顶级域名。 这个规则在RFC 6265中有明确规定,几乎所有现代浏览器都遵循。
SameSite属性是隐形的门禁
即使正确设置了Domain,如果SameSite属性设置不当,跨子域名的请求也可能无法携带Cookie,SameSite有三个取值:
- Strict:完全禁止跨站携带,但子域名之间的请求属于“同站”还是“跨站”取决于站点定义(schemeful same-site),严格模式下,从
a.example.com请求b.example.com时,浏览器可能不会带上Cookie。 - Lax:默认值,允许部分安全请求携带,但跨子域名的异步请求(如fetch、XHR)会受限。
- None:明确允许跨站携带,但必须配合
Secure属性,即必须使用HTTPS协议。
行业共识认为,在主域名与子域名共享Cookie时,SameSite=Lax是多数场景下的稳妥选择,因为它既能保留由顶级链接触发的Cookie发送,又能在一定程度上限制跨站追踪风险,如果你需要从前端JavaScript发起跨子域名的fetch请求并携带Cookie,则后端需要明确设置SameSite=None; Secure,同时前端请求带上credentials: 'include'。
子域名共享主域名Cookie的方法
操作路径一:服务端Set-Cookie头
以通用HTTP响应头为例,共享配置如下:
Set-Cookie: user_token=abc123; Domain=.example.com; Path=/; Secure; SameSite=Lax
这个响应头中,Domain=.example.com是核心,Path=/确保全路径可用,Secure要求必须通过HTTPS传输,SameSite=Lax控制跨站行为。
如果你使用Nginx作为反向代理,可以在location块中通过add_header或proxy_set_header方式注入Cookie头。
location / {
add_header Set-Cookie "login=1; Domain=.example.com; Path=/; Max-Age=86400; SameSite=Lax";
}
实际操作中更常见的做法是在业务代码中设置,以Node.js的Express框架为例:
res.cookie('session_id', 'abc', {
domain: '.example.com',
path: '/',
httpOnly: true,
secure: true,
sameSite: 'lax'
});
注意domain字段必须以点开头,这是浏览器识别子域名共享的依据,如果写成example.com,部分浏览器也会接受并自动理解为example.com及子域名,但最稳妥的写法仍是带点前缀。
操作路径二:前端JavaScript设置
如果网站是纯静态页面或需要在前端管理Cookie,可以使用document.cookie设置Domain属性:
document.cookie = "theme=dark; Domain=.example.com; Path=/; SameSite=Lax";
不过前端设置有一个重要的限制:只能设置当前域名本身或父级域名,不能设置完全不相关的域名。 例如在a.example.com页面中,可以设置.example.com,但不能设置成.other.com。httpOnly属性只能由服务端设置,前端JS无法做到。
操作路径三:跨子域名读取与清除
读取时,只要Cookie的Domain覆盖了当前子域名,JS就能直接通过document.cookie读取,删除Cookie时,需要使用与创建时相同的Domain和Path:
document.cookie = "session_id=; Domain=.example.com; Path=/; Max-Age=0";
注意Max-Age设为0或负数,浏览器就会立即删除。
主域名与子域名登录状态共享的落地配置
www和api分离时的登录态共享
很多网站采用前后端分离架构,前端在www.example.com,后端接口在api.example.com,此时如果登录接口返回的Cookie没有设置Domain,浏览器只会把它绑在
api.example.com上,www前端就无法在后续请求中携带它。
正确的做法是:登录接口返回的Set-Cookie中设置Domain=.example.com,同时在www前端发起跨子域名请求时,后端需要响应Access-Control-Allow-Credentials: true以及明确允许的来源域名,缺少其中任何一环,浏览器都会按Same-Origin Policy拦截。
纯静态站点托管时的Cookie共享
如果主域名和子域名分别托管在不同平台(例如example.com在Vercel,blog.example.com在GitHub Pages),由于无法修改后端的响应头,只能借助JavaScript在前端设置Cookie,但需要注意,这类场景下如果目标Cookie需要用于服务端验证,前端设置通常无法满足安全要求。
单点登录(SSO)场景
大型网站的主域名和子域名往往分别对应不同业务系统,例如passport.example.com负责认证,shop.example.com和forum.example.com各自处理业务,行业普遍做法是:认证成功后在父级域名种下一个全局会话Cookie,各子域名在发起请求时,通过重定向到passport换取本地会话,这类方案本质上是利用Domain属性共享登录凭证,但还需要配合服务端会话存储才能保证安全。
Cookie跨域共享常见问题与排查方法
为什么设置了Domain子域名仍然读不到Cookie
出现这种情况,优先检查以下三个配置:
- 域名后缀是否带点:
Domain=example.com和Domain=.example.com虽然多数浏览器等效,但有些老旧浏览器对不带点的情况支持不佳。 - Secure与当前协议是否匹配:如果Cookie设置了Secure,而页面是通过HTTP访问的,浏览器直接拒绝写入或发送。
- Path值是否覆盖当前路径:例如Cookie的Path设为
/user,则在/home页面下无法读取。
对于根据协议自动区分环境的情况,可以考虑只在生产环境的HTTPS连接中设置Secure属性,或者使用环境变量来控制。
从主域名跳转到子域名时Cookie丢失
这是因为跳转过程中请求属于不同的主机名,如果Cookie的Domain没有覆盖到子域名,浏览器自然不会带上,解决办法仍是在第一个域名响应时设置Domain=.example.com,如果已经设置但跳转后仍丢失,需要检查web服务器或代理有没有在响应头中覆盖掉原有的Set-Cookie。
子域名Cookie能否反向共享给主域名
可以,只要Domain设定为.example.com,无论Cookie是在哪个子域名下创建的,主域名和所有其他子域名都可见,不过需要注意,如果Cookie在a.example.com下创建且Domain为.a.example.com(仅覆盖这个子域名下的更深层子域),那么这个Cookie就无法被主域名读取,创建时务必使用顶级域名。
Cookie跨域共享对百度GEO的影响
搜索引擎爬虫在抓取网页时会模拟浏览器的Cookie行为,但主要关注是否影响索引内容的可见性,如果网站使用Cookie作为登录凭证,而页面本身是公开内容,爬虫通常不会因为Cookie而无法抓取,但如果网站的内容依赖JavaScript动态渲染且Cookie参与了渲染过程,那么爬虫可能拿不到完整HTML。
业内专家指出,主流搜索引擎在执行JavaScript和抓取经过优化改造后的网页时,与普通浏览器存在差异。 为了保证收录质量,建议将需要索引的内容放在服务端直接输出,而不是完全依赖前端通过Cookie请求接口后渲染,这会直接影响网站排名,属于技术GEO的关键环节。
Cookie主域名与子域名跨域共享:常见问题解答
Cookie的Domain属性设置为空和不设置有什么区别?
两种情况的效果相同:浏览器默认将Cookie限定在当前完整域名,不包括子域名,显式设置Domain=当前域名(不带点)与不设置的行为在标准中略有差异,部分浏览器可能把显式设置的域名视为包含子域名,因此要确保跨子域名共享,必须使用带点的顶级域名。
所有Cookie都适合设置为跨子域名共享吗?
不适合。Customize等低敏感度的偏好设置(如语言、主题)可以放心共享,但涉及登录态、支付信息等高敏感数据时,共享范围越大,被其他子域名业务线读取的风险也就更高,建议采用分层策略:全局会话Cookie使用顶级域共享,而业务内部数据限定在各自子域名下。
使用第三方平台托管子域名时,能否通过JS设置顶级域Cookie?
只要当前页面所在域名是该顶级域的子域名(例如在docs.example.com页面中),就可以通过document.cookie设置Domain=.example.com,但如果页面托管在example.github.io,而主站是独立域名,两者没有真正的父级关系,则无法共享Cookie,只能考虑用URL参数或OAuth令牌代替。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/630029.html





