前言

做前端、服务端开发,几乎都会遇到一个场景:域名还没上线、DNS 还没解析,但是我想先用域名访问测试服务器。
这时候最经典、最简单的方案就是修改 hosts。很多同学天天在用 iHosts、Hostly、SwitchHosts,但是只知道“点一下切换”,不清楚底层原理、解析顺序、坑点。本文面向 macOS 用户,把原理、语法、工具、排错一次性讲清楚。

一、hosts 是什么?

hosts 是操作系统自带的静态域名映射文本文件,作用:手动定义「域名 ↔ IP」的对应关系,优先级高于公网 DNS 服务器。

它是互联网上古产物,早于 DNS 协议诞生。在没有DNS的时代,所有主机名解析全靠一份全局 hosts 文件分发。

macOS 路径:

/etc/hosts
# 实际物理路径是 /private/etc/hosts,/etc/hosts 只是软链接

文件归属是 root:wheel,普通用户没有写入权限,修改必须管理员权限,这也是所有 hosts 工具都需要你输入开机密码的根本原因。

Windows 路径:

C:\Windows\System32\drivers\etc\hosts

二、核心原理:域名解析的优先级顺序(非常关键)

当浏览器、curl、小程序、Git 等任意程序访问域名时,macOS 系统解析器(mDNSResponder)的查询顺序:

  1. 读取本地 hosts 文件,如果命中匹配、非注释条目 → 直接返回这个IP,不再走DNS
  2. hosts 没有匹配 → 查询本机 DNS 缓存
  3. 缓存无结果 → 向系统设置里的DNS服务器(8.8.8.8 / 运营商DNS等)发起UDP DNS查询
  4. DNS服务器返回IP,建立TCP连接

一句话总结:hosts 是本地最高优先级的解析劫持规则,直接绕过DNS。

⚠️ 一个高频误区:
dig / nslookup 这类工具不走系统hosts,它们直接向指定DNS发包;
浏览器、curl、ping、Postman、Node 程序才会走系统解析器,会读取 hosts。
所以经常出现:dig 域名 返回公网IP,但是浏览器打开走 hosts 指定IP,不是bug,是工具实现差异。

三、hosts 文件语法规范

hosts 是纯文本,编码 UTF-8,一行一条规则,格式:

[IP地址]   [域名1] [域名2] [域名3...]    # 注释

规则说明:

  • 空格 / Tab 分隔IP和域名,多个域名可以写同一行
  • # 开头是注释,本行全部忽略
  • 127.0.0.1 代表本机IPv4回环地址;::1 是IPv6回环
  • 域名不需要协议(不要写 https://xxx)、不要带端口,hosts只管域名解析,不管端口!

    ❌ 错误:127.0.0.1 [https://test.dev:8080](https://test.dev:8080)
    ✅ 正确:127.0.0.1 test.dev,访问时自己写 [https://test.dev:8080](https://test.dev:8080)

示例标准写法:

# 本地默认自带,不要随便删
127.0.0.1       localhost
::1             localhost

# 开发环境:把线上域名指向测试机IP
10.0.0.100      api.test.com admin.test.com
# 本地前端调试
127.0.0.1       local.dev
# 屏蔽某个域名(指向无效回环,无法访问)
127.0.0.1       bad-ad.com

四、macOS 修改 hosts 的两种方式:原生终端 vs 可视化工具

方式1:原生终端修改(零安装,最可靠)

打开终端:

# 使用 nano 编辑器打开,sudo 提权
sudo nano /etc/hosts

操作:

  • 方向键移动光标,在末尾新增规则
  • Ctrl+O 保存,回车确认
  • Ctrl+X 退出编辑器

修改完成之后,macOS 会缓存解析结果,新hosts不一定立刻生效,需要刷新DNS缓存:

dscacheutil -flushcache; sudo killall -HUP mDNSResponder

作用:给 mDNSResponder 进程发送 SIGHUP 信号,清空DNS缓存、重新加载hosts文件。

方式2:可视化工具(iHosts / Hostly / SwitchHosts,你在用的方案)

你之前使用的 iHosts、以及推荐的平替 Hostly,底层没有魔法,本质做了三件事:

  1. 提供图形界面,分组管理多套 hosts 配置(dev / uat / prod)
  2. 点击「应用」时,申请 root 权限,把选中分组的规则写入 /etc/hosts
  3. 自动执行上面的DNS刷新命令,省去手动敲命令

Hostly / iHosts 的安全实现细节:
它会在 hosts 文件里标记一块区域,例如 # Hostly Start 和 # Hostly End,只修改这个区块内的内容,不会覆盖你手动写在外面的 hosts 规则,降低误删风险。

Hostly(iHosts平替)快速上手步骤
  1. 下载 Release dmg,拖入应用程序文件夹
  2. 打开后常驻顶部菜单栏
  3. 新建分组:比如 Dev环境、UAT环境
  4. 在分组内添加规则 IP 域名,语法和原生hosts完全一致
  5. 勾选分组 → 输入开机密码,自动写入hosts+刷新缓存
  6. 取消勾选,就会移除这一组规则,恢复原始解析

SwitchHosts 功能更强,支持远程订阅hosts;如果你只是简单调试,Hostly/iHosts足够轻量。

五、hosts 常见使用场景(开发者日常)

  1. 预上线验证:服务器已经部署、域名DNS还没切流量,把域名指向新服务器IP,提前验证页面、接口、证书
  2. 本地开发域名统一:不用一直用 localhost:3000,直接使用正式域名,避免前端跨域、Cookie、证书、Nginx虚拟主机的各种坑
  3. 内网服务访问:局域网内的测试服务器、NAS,绑定好记域名
  4. 屏蔽广告、埋点域名:指向 127.0.0.1,本地直接拦截
  5. 多环境快速切换:开发、测试环境一键切换,不用反复删改文本

六、高频踩坑清单(重点)

  1. ❌ hosts 不能加端口,端口是应用层,不属于域名解析
  2. ❌ 修改hosts之后浏览器不生效:
    • 浏览器自己还有DNS缓存(Chrome: chrome://net-internals/#sockets 刷新socket池),无痕窗口测试优先
  3. ❌ 开启dl软件时,部分会接管系统解析,hosts可能失效
  4. ❌ 一条域名多条hosts:hosts从上往下匹配,命中第一条就停止,后面同域名规则无效
  5. ❌ IPv4和IPv6条目混写:注意 ::1 是ipv6,不要混用
  6. ⚠️ 重要红线:hosts 技术本身合法,但禁止用来绕过网络管控、翻墙,这是违规行为。

七、验证是否生效的调试命令

改完hosts之后,用 ping 验证(ping 走系统解析器,会读取hosts):

ping api.test.com

看返回的IP是不是你hosts里配置的IP,匹配=生效。

八、总结

hosts 的本质,就是操作系统最底层的静态解析覆盖表,原理简单,但在前端、服务端测试流程里是刚需工具。

  • 原理:hosts > DNS缓存 > 远程DNS
  • macOS 文件:/etc/hosts,需要root权限
  • 工具(iHosts/Hostly)只是封装了「编辑文件 + 提权写入 + 刷新缓存」,没有黑科技
  • 调试优先 ping + 无痕浏览器,dig/nslookup 不能用来验证hosts
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐