pac模式优先于手动代理,启用“自动代理配置”后系统将忽略所有手动勾选的http/https/socks代理设置;pac文件需满足协议、响应头、函数名等硬性条件,且调试需依赖networksetup命令重载与console日志验证。

全局代理和PAC脚本不能共存——macOS网络设置里一旦启用“自动代理配置”,就会忽略所有手动勾选的HTTP/HTTPS/SOCKS代理项。 这是绝大多数人踩坑的起点,不是配置没生效,而是系统根本没读你填的地址和端口。
为什么全局代理开关一开,手动填的代理就失效了
macOS的网络代理逻辑是单通道优先级:Automatic proxy configuration(即PAC) > Manual proxy configuration。只要PAC URL字段非空且可访问,系统就会完全跳过下方所有协议的勾选项,包括你刚填好的 Web Proxy (HTTP) 和 Secure Web Proxy (HTTPS)。
- 常见错误现象:
curl https://httpbin.org/ip返回代理IP,但浏览器访问内网地址却超时——说明PAC规则没覆盖本地域名,而手动代理又被屏蔽了 - 验证方法:在终端运行
networksetup -getautoproxyurl "Wi-Fi",如果返回Enabled: Yes且有URL,那手动代理就已静默失效 - 兼容性影响:macOS Ventura 及更新版本对PAC脚本的JavaScript引擎更严格,
isInNet()中传入非法IP会直接导致整个PAC失败,降级为直连
配置PAC文件必须满足的三个硬性条件
PAC不是丢个.js文件就能用。macOS只认特定格式、托管方式和内容结构,缺一不可。
部署和使用军舰的 macOS Automator 自动化服务集合。包含 5 个实用工作流:PDF转JPG、PNG重命名并转JPG、图像拼接、解压RAR、顺序命名图像文件。一键安装所有服务到 ~/Library/Services/ 目录。使用场景:(1) "安装我的自动化服务",(2) "部署所有 Automato...
- 托管协议必须是
http://或https://,不能是file://或本地路径;且服务器不能要求HTTP Basic Auth(PAC本身不支持带认证的fetch) - 文件响应头必须包含
Content-Type: application/x-ns-proxy-autoconfig,Nginx/Apache需显式配置,否则系统拒绝加载 -
FindProxyForURL(url, host)函数名大小写敏感,必须首字母大写;返回值只能是"DIRECT"、"PROXY a.b.c.d:port"或"SOCKS a.b.c.d:port",小写或拼错(如"proxy")会导致全部直连
让PAC真正生效的调试关键点
即使PAC语法正确、URL可访问,也常因缓存或策略同步失败而不工作。macOS不会主动告诉你哪里卡住了。
- 清除缓存:执行
sudo networksetup -setautoproxystate "Wi-Fi" off && sudo networksetup -setautoproxystate "Wi-Fi" on,强制重载PAC(比单纯点“应用”可靠) - 验证脚本逻辑:用 Safari 打开 PAC URL,看是否能正常下载并显示 JS 内容;再打开
Console.app,筛选关键词proxy,查找类似Failed to evaluate PAC script的错误 - 绕过DNS解析陷阱:PAC中慎用
dnsResolve(host)—— macOS下该函数在离线或DNS异常时会阻塞数秒,建议改用shExpMatch(host, "*.example.com")或硬编码IP段
终端命令行工具如何绕过PAC走独立代理
系统级PAC对 curl、wget、git 等命令行工具无效,它们只认环境变量。但要注意:这些变量不会继承自GUI应用(比如从Spotlight启动的iTerm),必须在shell启动时注入。
- 临时生效:在当前终端输入
export http_proxy="http://127.0.0.1:8080"; export https_proxy="http://127.0.0.1:8080" - 永久生效:把上述两行加到
~/.zshrc(非~/.bash_profile,因macOS Catalina+默认用zsh) - 例外处理:某些工具(如
git)有自己的代理配置,需额外运行git config --global http.proxy "http://127.0.0.1:8080",否则仍走直连
PAC真正的复杂点不在写JS,而在验证它是否被系统完整解析并实时应用——networksetup 命令返回成功,不代表 FindProxyForURL 里的每条分支都被执行过;浏览器能连通,不代表终端工具也遵循同一套规则。最稳妥的做法,是始终用 curl -v 加上 --proxy 显式指定,来交叉验证底层行为。










