JavaScript如何正确获取网站顶级域名以实现跨子域Cookie设置
你当前的实现仅能覆盖「单级子域+单段顶级域」的简单场景,存在两个明显缺陷:
- 处理多级子域时结果错误:例如域名是
a.b.c.google.com,按照你的逻辑会返回b.c.google.com,而非目标根域名google.com - 无法适配多段公共后缀场景:例如
.co.uk/.com.cn这类复合顶级域,若域名是shop.co.uk,你的逻辑会返回co.uk,而该域名属于公共后缀,普通站点无权在此层级设置Cookie
推荐实现方案
方案1:浏览器端无依赖测试方案
利用浏览器自带的Cookie域名校验逻辑自动识别合法根域名,兼容性好,无需手动维护后缀列表:
function getRootDomain() { const hostname = location.hostname; const segments = hostname.split('.'); // 从最短的可能根域名开始向上测试 for (let i = segments.length - 2; i >= 0; i--) { const testDomain = segments.slice(i).join('.'); const testKey = `__root_test_${Math.random().toString(36).slice(2)}`; // 尝试设置测试Cookie document.cookie = `${testKey}=1;domain=${testDomain};path=/;max-age=10`; // 校验是否设置成功 if (document.cookie.includes(testKey)) { // 清理测试Cookie document.cookie = `${testKey}=;domain=${testDomain};path=/;max-age=0`; return testDomain; } } // 兜底返回当前域名 return hostname; }
该方案会自动适配所有公共后缀场景,无论是单段的.com还是多段的.co.uk都能正确返回可设置Cookie的最高层级域名。
方案2:前后端通用匹配方案
如果需要在非浏览器环境使用,可以基于公共后缀规则匹配,轻量实现如下:
// 可根据业务覆盖的区域补充更多多段公共后缀 const MULTI_PUBLIC_SUFFIX = new Set([ 'co.uk', 'com.cn', 'net.cn', 'org.cn', 'gov.cn', 'ac.uk', 'co.jp', 'co.kr', 'com.hk' ]); function getRootDomain(hostname) { const segments = hostname.split('.'); if (segments.length <= 2) return hostname; const lastTwoSegments = segments.slice(-2).join('.'); // 最后两段为多段公共后缀时,取最后三段作为根域名 if (MULTI_PUBLIC_SUFFIX.has(lastTwoSegments)) { return segments.slice(-3).join('.'); } // 否则取最后两段 return lastTwoSegments; }
如果需要覆盖全球所有公共后缀场景,可以引入成熟的PSL(公共后缀列表)解析库,无需自行维护后缀规则。
内容的提问来源于stack exchange,提问作者Rolintocour
相关产品推荐
相关产品推荐

