一、为什么在部分场景下 PAC 依然不可替代
现在很多人习惯了路由高级分流或 TUN 模式。
但在很多特殊的网络环境下,这两个现代方案会直接撞墙:
企业内网准入安全软件:许多金融公司或政企内网部署了严格的终端安全防护系统,一旦检测到机器创建了未授权的虚拟网卡(TUN/Wintun),会直接判定为异常入侵并切断整机内网网络;
多开发工具特定代理绑定:部分老旧的自动化测试工具或嵌入式 Web 控制台,只认系统注册表里的 `AutoConfigURL` 脚本。
这时候,基于标准 JavaScript 语法的 PAC(Proxy Auto-Configuration)就是唯一合规且轻量级的解法。
它不需要任何底层驱动权限,仅仅依靠一段几十行的轻量脚本,就能指挥系统里的所有 Web 请求:哪些域名直连本地局域网,哪些域名打向 10809 代理端口。
二、PAC 文件的核心灵魂:FindProxyForURL 函数

在 v2rayN 的运行目录里,PAC 模式的基石是一个名为 `pac.txt` 的纯文本文件。
浏览器的每一次网络发包,都会先执行这个文件里的入口函数:
function FindProxyForURL(url, host) {
// 返回值说明:
// "DIRECT" -> 流量不走代理,直接连接目标服务器
// "PROXY 127.0.0.1:10809" -> 流量转交本地 HTTP 代理端口
// "SOCKS5 127.0.0.1:10808" -> 流量转交本地 Socks5 代理端口
}
很多用户自己改了 `pac.txt` 却发现完全不起作用,往往是因为函数体内抛出了未捕获的语法错误,导致 Windows 底层的 WinINet 引擎直接降级回默认直连。
三、从零定制你的专属 PAC 规则池
步骤 1:定位并解构本地 pac.txt 文件
打开 v2rayN 所在目录,进入 `pac` 文件夹。
找到 `pac.txt`(如果不存在,在 v2rayN 底部托盘图标右键,选择「系统代理」 -> 「PAC 模式」,软件会自动从内置模板释放该文件)。
用专业文本编辑器打开它。
步骤 2:注入企业内网与私有域名直连白名单
找到函数体的开头部分,在最上方插入你的高优先级直连判定代码。最健壮的写法是利用 `shExpMatch` 或 `dnsDomainIs` 内置函数:
function FindProxyForURL(url, host) {
// 1. 本地回环与内网广播地址无条件直连
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// 2. 自定义企业内网专属域名与本地开发服务直连
if (shExpMatch(host, "*.oa.company.com") ||
shExpMatch(host, "*.dev.corp") ||
shExpMatch(host, "git.myteam.net")) {
return "DIRECT";
}
// 3. 需要走代理的目标域名列表
if (shExpMatch(host, "*.google.com") ||
shExpMatch(host, "*.github.com") ||
shExpMatch(host, "*.openai.com")) {
return "PROXY 127.0.0.1:10809; DIRECT";
}
// 4. 其余流量默认走直连(国内白名单模式)
return "DIRECT";
}
步骤 3:强制刷新 Windows 系统的 PAC 脚本缓存
改完 `pac.txt` 后,直接刷新网页往往看不到变化,这是因为 Windows 会将 PAC 结果在内存中强行缓存几十分钟:
打开 Windows 设置,进入「网络和 Internet」 -> 「代理」。
找到「使用设置脚本 (PAC)」,检查脚本地址是否为类似 `http://127.0.0.1:10809/pac/pac.txt`。
关键动作:先将「使用设置脚本」的开关关闭,点击保存;等待 3 秒后再次开启并保存。
按 `Win + R` 打开运行框,输入 `cmd` 执行以下命令清空本地 DNS 与 Winsock 缓存:
```cmd
ipconfig /flushdns
```
四、排查 PAC 失效的三个隐秘陷阱
- 不要在 PAC 中写耗时的 `dnsResolve` 循环:如果在规则里写了大量的 `isInNet(dnsResolve(host), ...)`,每次访问域名系统都会同步发起一次 DNS 查询。遇到打不开的死域名,浏览器会卡死假死十几秒。优先使用基于纯字符串匹配的 `shExpMatch(host, ...)`。
- 文件编码必须是 UTF-8 无 BOM:如果用系统记事本保存成了带有 BOM 头的 UTF-8 或者 ANSI 格式,WinINet 引擎会把文件首字节当成乱码直接报错终止解析。