(开头提问)昨晚有个实习生问我:"为啥用window.location.href拿到的域名带着烦人的端口号?"这话可把我问住了——当年我在这坑里摔得鼻青脸肿。今天咱就掰开了揉碎了讲讲,JS里获取域名那些门道。
一、基础篇:五大核心方法实测
(自问自答)Q:不都是拿域名吗?搞这么多方法干啥?
A:举个栗子,就像你去超市买西瓜,用手拍、用秤称、看纹路...不同场景需要不同姿势。
方法对比表收好:
方法 | 输出示例 | 适用场景 | 坑点 |
---|---|---|---|
window.location.hostname | "http://www.example.com" | 精准获取 | 不包含端口 |
document.domain | "example.com" | 同源策略 | 需手动设置 |
window.location.host | "http://www.example.com:8080" | 带端口调试 | 需二次处理 |
URL API | new URL(url).hostname | 现代浏览器 | IE不兼容 |
location.ancestorOrigins | ["https://parent.com"] | 嵌套iframe | 需权限授权 |
上周给某电商平台做迁移,就因为用了document.domain导致CDN资源加载失败,差点背锅离职。切记:主域名不同千万别硬改document.domain!
二、实战篇:跨域场景生存指南
场景1:iframe父子通信
最近接手个老项目,父窗口域名是"a.com",内嵌iframe是"b.a.com"。这时候在iframe里用:
js**console.log(window.parent.location.hostname); // 直接报安全错误
正确姿势应该是:
js**// 父子页面都要设置document.domain = 'a.com';// 然后才能安全获取const parentDomain = window.parent.location.hostname;
场景2:第三方SDK开发
做微信分享插件时遇到个奇葩问题——在"http://www.x.com"和"x.com"之间反复横跳。最终方案:
js**const rootDomain = window.location.hostname.split('.').slice(-2).join('.');// 输出"x.com"统一处理
场景3:本地开发调试
新手常犯的错是在localhost环境写死域名。推荐用动态判断:
js**const isProd = /\.(com|cn)$/.test(window.location.hostname);const API_URL = isProd ? 'https://api.example.com' : 'http://localhost:3000';
三、避坑篇:血泪换来的7条军规
SSL证书引发的惨案:
当你的域名带www时,必须确保裸域名(如example.com)也有证书,否则iOS Safari会抽风浏览器隐私模式陷阱:
Chrome的incognito模式会屏蔽某些域名获取方法,去年我们灰度测试就栽在这国际化域名(IDN)乱码:
处理中文域名要用punycode转换:js**
'北京大学.cn'.replace(/\./g, '');// 输出"xn--1lq90ic7f1rc.cn"
微信内置浏览器特例:
在微信里打开第三方页面,location.hostname可能返回"wx.tenpay.com"这种中间域名SSR渲染的坑:
服务端渲染时window对象不存在,得用process.env.SERVER_DOMAIN替代
域名缩写识别:
英国.co.uk这类国别域名要做特殊处理,别用简单的split('.')[-2]
- IP直连场景:
当用户直接访问IP地址时,hostname会是"172.168.1.1",记得加异常处理
(个人观点)说句得罪人的话:现在很多新手迷恋window.location,却不知道performance.getEntries()这类高级API能挖出更多域名信息。不过切记——别在代码里写死域名,这跟把银行卡密码贴显示器上一个性质。最后送大家个彩蛋:试试在浏览器控制台输入document.cookie = 'test=1; domain=' + location.hostname.split('.').slice(-2).join('.')
,你会回来点赞的。