document.domain仅适用于同主域不同子域场景,无法解决Session共享,需配合postMessage、服务端Cookie Domain设为.example.com及credentials: 'include'等措施。

document.domain 不能解决 Session 共享,只影响 JS 同源判断;它只是跨子域通信的起点,不是终点。
document.domain 的适用边界在哪
它只对「同主域、不同子域」有效,比如 a.example.com 和 b.example.com。一旦涉及不同根域名(如 example.com 和 other.com),或协议/端口不一致(http:// vs https://),document.domain 直接失效。
常见错误现象:
- 父页设了
document.domain = "example.com",iframe 也设了,但iframe.contentWindow.document仍报Access denied - 控制台没报错,但
postMessage收不到回执 —— 实际是targetOrigin写错了,不是document.domain没生效
关键点:父页和 iframe 页面都必须显式设置,且值完全一致;设置必须在任何 DOM 访问或脚本执行前完成(最好放在 <script> 开头第一行)。
立即学习“前端免费学习笔记(深入)”;
为什么 document.cookie 在 iframe 里读不到父页的 session
因为 Cookie 的发送逻辑和 JS 同源判断是两套机制:document.domain 只改前者,不影响后者。浏览器仍按原始完整域名发 Cookie,a.example.com 的请求不会携带 b.example.com 的 Cookie。
要让 session 可见,必须服务端配合:
- Cookie 的
Domain属性必须设为.example.com(注意开头的点) - 前端发起请求时需带上凭据:
credentials: 'include' - 服务端响应头需允许凭据:
Access-Control-Allow-Credentials: true
PHP 示例中漏掉点号(example.com)或 Express 中写成 'example.com',都会导致跨子域 Cookie 不发送。
postMessage + document.domain 协同使用的实操要点
单纯靠 document.domain 解除限制后,仍需用 postMessage 安全传数据,不能直接操作对方 DOM —— 尤其在现代浏览器中,即使同 domain,若 iframe 加载了第三方资源或存在 CSP 策略,DOM 访问也可能被拦截。
推荐写法:
// 父页(a.example.com)
document.domain = 'example.com';
const iframe = document.getElementById('myFrame');
iframe.onload = () => {
iframe.contentWindow.postMessage({ type: 'AUTH_CHECK' }, 'https://b.example.com');
};
window.addEventListener('message', e => {
if (e.origin !== 'https://b.example.com') return;
console.log('收到子页响应:', e.data);
});
注意:targetOrigin 必须写完整协议+域名,不能用 *(否则服务端凭据策略会拒绝);e.origin 必须校验,防止伪造消息。
容易被忽略的兼容性与安全陷阱
document.domain 在 Chrome 88+、Firefox 79+ 已被标记为“deprecated”,未来可能移除;Safari 对它的支持始终较弱,尤其在 iOS 上常静默失败。
更现实的风险点:
- 父页和 iframe 页面的
document.domain设置时机不一致(比如 iframe 页面异步加载 JS 后才设置),导致通信时仍被判定为跨域 - 页面启用了
Strict-Transport-Security或Content-Security-Policy,禁止修改document.domain - 某些企业级代理或安全网关会剥离
Cookie的Domain属性,导致.example.com被重写为example.com
真正稳定的跨子域方案,是把 document.domain 当作辅助手段,核心依赖 postMessage + 后端统一 Cookie 域 + 凭据透传,三者缺一不可。



















