在 Web 开发中,我们经常会修改 hosts 文件,也会遇到“跨域(CORS)”报错,或者纳闷“为什么 Cookie 存不上”。这一切的核心,都在于我们如何定义“同一个域名”。
本文结合本地开发环境配置,总结域名的三种判断标准及其应用场景。
一、 起点:Hosts 文件中的“域名”
我们在 /etc/hosts (for Macbook)中配置如下内容时:
127.0.0.1 sso.dev.com
127.0.0.1 local.mcp.tester.com
这里的逻辑是:DNS 劫持。
- 判断标准: 完全限定字符串 (FQDN) 。
- 原理: 操作系统只看字符串。只要字符不完全一样,它们就是两条独立的记录。
- 结论: 哪怕它们都指向
127.0.0.1(同一台电脑),在操作系统看来,这是两个完全不相干的“门牌号”。你配置多少个都可以,互不冲突。
二、 核心:浏览器眼里的“同源策略” (Same-Origin Policy)
当你打开浏览器访问这些地址时,规则就变了。浏览器为了安全,设置了一堵高墙,叫同源策略。
这是前端开发中最常遇到“跨域(CORS)”问题的根源。
1. 什么是“同一个域”?
浏览器认为,只有当 协议 + 域名 + 端口 三者完全一致时,才算“自己人”(同源)。
假设你的当前页面是:http://sso.dev.com:80
| 比较对象 | 结果 | 为什么? | 后果 |
|---|---|---|---|
http://sso.dev.com/api | ✅ 同源 | 三者全同 | AJAX 请求成功,Cookie 可读取 |
https://sso.dev.com | ❌ 跨域 | 协议不同 (https) | 请求被拦截 |
http://sso.dev.com:8080 | ❌ 跨域 | 端口不同 (8080) | 请求被拦截 |
http://api.dev.com | ❌ 跨域 | 域名不同 (子域不同) | 请求被拦截 |
http://local.mcp.tester.com | ❌ 跨域 | 域名完全不同 | 请求被拦截 |
2. 这里的坑点
即使在 hosts 里,sso.dev.com 和 local.mcp.tester.com 实际上指向的是同一台机器 (127.0.0.1),浏览器并不关心物理 IP。
浏览器只看地址栏里的字。因为名字不同,浏览器就会把它们当作陌生人,默认禁止它们互相读取数据(LocalStorage)或发送 AJAX 请求。
三、 特例:Cookie 的“认亲”规则 (Root Domain)
虽然同源策略很严格,但在做 单点登录 (SSO) 时,我们需要在不同的子域名之间共享登录状态。这时候使用的是**“根域名”**标准。
- 场景: 让
sso.dev.com和api.dev.com共享 Cookie。 - 规则: 只要根域名(Root Domain)相同,就可以共享。
- 操作: 设置 Cookie 时指定
Domain=.dev.com。
对比你的配置:
sso.dev.com(根域名:www.google.com/search?q=de…)local.mcp.tester.com(根域名:www.google.com/search?q=te…)
结论: 这两个域名的“祖宗”都不同,所以无论如何配置,它们之间无法通过常规方式共享 Cookie。
四、 开发环境实战总结
回到最初的 hosts 配置图:
-
配置安全性:
将多个不同域名指向
127.0.0.1是完全正确且安全的。这在微服务开发中很常见(模拟不同的服务环境)。 -
服务区分:
因为域名不同,你需要确保你的本地 Web 服务器(Nginx/Apache)配置了不同的
VirtualHost或server_name,以便根据域名转发到不同的项目代码目录。 -
跨域调试:
如果你的前端运行在
sso.dev.com,而后端接口在local.mcp.tester.com:- 现象: 浏览器会报 CORS 错误。
- 解决: 你需要在后端代码或 Nginx 中添加 CORS 响应头(
Access-Control-Allow-Origin),允许前者访问后者。
一图胜千言
- Hosts 文件: 只要名字不一样,就是不同的记录。(负责指路)
- 同源策略: 只要字有一个不一样,就是跨域。(负责安保)
- Cookie: 只要姓氏(根域名)一样,就是一家人。(负责共享)