PAC全称Proxy Auto-Config,本质是一份写满规则的JavaScript文件。浏览器访问网站的时候,会先运行这个脚本,脚本根据访问的网址给出指令,决定这个请求直接联网,还是走代理。好处是不用手动来回开关代理,国内网站直连、境外网站走代理,全部交给脚本自动判断。
PAC文件本身就是纯文本JS文件,不能包含任何HTML标签,文件里必须定义FindProxyForURL(url, host)这个函数。url代表完整访问网址,host是主机域名。函数返回的内容,会直接决定浏览器后续的网络行为。
函数返回有三种基础写法。DIRECT代表直接连接,不走任何代理;PROXY ip:port使用HTTP代理;SOCKS ip:port使用SOCKS代理。多个规则可以用分号隔开,前面的代理连接失败,就自动尝试后面的选项。举个例子,返回"PROXY 1.2.3.4:8080; DIRECT",含义是优先尝试这个代理,代理无法连通就切换直连兜底。

编写PAC规则,几个内置函数使用频率最高。shExpMatch(host, ".google.com")用来做通配符匹配;dnsDomainIs(host, ".internal.com")精准匹配域名后缀;isInNet(host, "10.0.0.0", "255.0.0.0")判断IP是否属于指定网段;isPlainHostName(host)用来判断是否是不带域名的本地主机名。
一份可以正常运行的分流脚本示例如下。脚本优先处理内网地址直连,接着匹配特定域名走代理,最后设置兜底策略。
function FindProxyForURL(url, host) {
// 内网和本地直连
if (isPlainHostName(host) ||
isInNet(host, "192.168.0.0", "255.255.0.0") ||
isInNet(host, "10.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// 公司内部服务直连
if (shExpMatch(host, ".internal.com")) {
return "DIRECT";
}
// 特定域名走代理
if (shExpMatch(host, "*.example.com")) {
return "PROXY proxy.mydomain.com:8080";
}
// 默认策略
return "PROXY proxy.mydomain.com:8080; DIRECT";
}
这份脚本顺序不能随意改动,代码从上往下依次执行,最先匹配成功的规则就会生效。
PAC 文件写好之后,需要放到可访问的位置。可以上传到 Web 服务器,使用http://你的域名/proxy.pac调用。内网封闭环境,也可以使用本地文件路径,Windows 格式写为file:///C:/config/proxy.pac,注意路径反斜杠要替换成正斜杠。
Firefox 配置入口在菜单,点击右上角三条横线打开设置页面,下滑找到网络设置,点击设置,选中自动代理配置 URL,粘贴 PAC 文件地址,确认保存。地址开头必须带上 http:// 或者 file://,地址前后不要留空格。
Chrome 浏览器没有独立 PAC 配置项,它读取 Windows 系统代理设置。打开控制面板,进入 Internet 选项,切换到连接标签,点击局域网设置,勾选使用自动配置脚本,填入 PAC 地址。Windows10、11 还可以走系统设置:网络和 Internet → 代理 → 自动代理设置,打开使用设置脚本,填入 URL 保存。
macOS 系统设置里找到网络选项,选中当前在用的网络连接,点击详细信息,进入代理页面,勾选自动代理配置,填写 PAC 地址。也可以使用命令行快速配置:networksetup -setautoproxyurl "Wi-Fi" "https://你的域名/proxy.pac",相比图形界面点击操作更快。
PAC 调试最常见的坑是缓存问题。修改脚本之后,浏览器依旧加载旧版本文件。调试阶段可以在脚本添加 alert () 语句,Firefox 打开浏览器控制台 Ctrl+Shift+J 查看输出;Chrome 访问 chrome://net-internals/#events,搜索 proxy 相关日志排查。更彻底的方案是在 Web 服务器设置 PAC 文件 HTTP 响应头 Cache-Control: no-cache,强制浏览器每次都拉取最新脚本。
语法错误也是高频问题。少写分号、括号不匹配、if 条件写反,浏览器不会弹出报错提示,只会出现所有请求直连或者全部网络请求失败的情况,很容易误以为是网络故障。部署之前,先用 JS 校验工具,或是 pacparser 这类 PAC 专用解析器本地运行,验证返回结果是否正常。