浏览器使用 PAC 时,ChatGPT、Claude 或 Gemini 进不进代理,看 FindProxyForURL 返回什么。返回 DIRECT 就是这一下不走代理。2026-11-06 把 Chromium 源码里的匹配函数放进 Node 22.23.4:只写带前导点的后缀,命不中顶点域名;不带点又会命中别的名字。例外名单是另一层,见 例外名单把 AI 网站留在直连。

OpenAI、Anthropic 和 Google 都没有把中国大陆写成这些产品的无条件服务地。把主机名改成走代理,不会把名单外的访问变成名单内。绕过地区检查可能违反条款,账号可能被限制或停用。本文不写伪造证件、购买或借用账号、手机号和支付卡。

先分开三种「没走代理」

一个可单独引用的判断句:PAC 的 DIRECT 只描述浏览器这一次把连接交给谁,不描述对方的地区名单。

你看到的结果更像哪一层下一步
系统代理开着,只有个别域名直连例外名单见例外名单一文。那篇不是 PAC
设置里是自动配置脚本,或写着自动检测本文的 PAC 或 WPAD先看脚本对这个主机名返回什么
浏览器超时,curl 指定代理却有 HTTP浏览器没进那条代理对照脚本的返回值,再看 curl
页面已经写出国家、地区或 territory名单或账号停止改脚本。见 Claude 与 Gemini 的地区报错和注册

桌面应用和官方 SDK 不读浏览器的 PAC。那种「网页可以、客户端不行」见 桌面应用不跟浏览器。

两个函数怎样比较主机名

MDN 的 PAC 说明 在 2026-11-06 把 dnsDomainIs 写成「当且仅当主机名的域匹配时返回 true」,并给了两个例子:dnsDomainIs("www.mozilla.org", ".mozilla.org") 为 true,dnsDomainIs("www", ".mozilla.org") 为 false。同一页把 shExpMatch 写成 shell 通配,不是正则;* 和 ? 总是可用。

Chromium 的 services/proxy_resolver/pac_js_library.h 当天从 main 打开。文件注释写明,这些函数上次从 Mozilla 的 netwerk/base/ProxyAutoConfig.cpp 抽出,修订号 6aa3b57955fed5e137d0306478e1a4b424a6d392,日期 2018-03-29。日志接口当天返回 503,所以没有 Chromium 的 commit。函数正文是:

function dnsDomainIs(host, domain) {
  return (host.length >= domain.length &&
          host.substring(host.length - domain.length) == domain);
}

function shExpMatch(url, pattern) {
  pattern = pattern.replace(/\./g, '\\.');
  pattern = pattern.replace(/\*/g, '.*');
  pattern = pattern.replace(/\?/g, '.');
  var newRe = new RegExp('^' + pattern + '$');
  return newRe.test(url);
}

这是后缀比较和通配,函数内部没有 DNS。当天用 Node v22.23.4 执行的是这份正文,不是一台安装好的 Chrome。MDN 的两个例子结果相同。和 AI 主机名有关的结果是:

调用结果
dnsDomainIs("chatgpt.com", ".chatgpt.com")false
dnsDomainIs("www.chatgpt.com", ".chatgpt.com")true
dnsDomainIs("notchatgpt.com", "chatgpt.com")true
dnsDomainIs("evilchatgpt.com", "chatgpt.com")true
dnsDomainIs("evilchatgpt.com", ".chatgpt.com")false
dnsDomainIs("gemini.google.com", ".google.com")true
dnsDomainIs("gemini.google.com", ".gemini.google.com")false
dnsDomainIs("mail.google.com", ".google.com")true
shExpMatch("chatgpt.com", "*.chatgpt.com")false
shExpMatch("www.chatgpt.com", "*.chatgpt.com")true
shExpMatch("notchatgpt.com", "*chatgpt.com")true

因此:带前导点的后缀漏掉顶点;不带前导点的后缀会命中 notchatgpt.com 这种尾巴;*.chatgpt.com 同样漏掉顶点;*chatgpt.com 又太宽。".google.com" 会同时命中 gemini.google.com 和 mail.google.com。

顶点要写成相等,子域再用带前导点的后缀:

host === "chatgpt.com" || dnsDomainIs(host, ".chatgpt.com")

isInNet 在同一份文件里,若参数还不是 IPv4 字面量,会先调用 dnsResolve。脚本若靠它决定直连,用的就是这一次解析。53 端口没到达你点名的解析器时,先看 53 端口被改道时,AI 域名先答错,不要先改地区设置。

脚本里怎样写这些主机名

下面不是公司网络的完整脚本,只避免上面两种误匹配。127.0.0.1:7890 换成你已经在用的本地 HTTP 代理。返回 PROXY 不会让出口变成支持地区。function 里先 return 的那条生效,写在后面的条件不再看。

function FindProxyForURL(url, host) {
  if (
    host === "chatgpt.com" || dnsDomainIs(host, ".chatgpt.com") ||
    host === "claude.ai" || dnsDomainIs(host, ".claude.ai") ||
    host === "gemini.google.com" || dnsDomainIs(host, ".gemini.google.com") ||
    host === "api.openai.com" ||
    host === "api.anthropic.com" ||
    host === "generativelanguage.googleapis.com"
  ) {
    return "PROXY 127.0.0.1:7890";
  }
  return "DIRECT";
}

api.openai.com 这三行是完整主机名,没有写成后缀,子域对不上。网页和 API 本来就不是同一台主机,见 网页能开,不代表 API 同一出口。不要写 .com,也不要为了省事写 .google.com:当天的函数会把 mail.google.com 和 gemini.google.com 看成同一个后缀。

若脚本先对 .google.com 返回 DIRECT,gemini.google.com 在到达后面的代理规则之前就已经直接出去。把 AI 主机名的判断放在这条 DIRECT 之前,或者不要用这么宽的后缀。

Chrome 怎样读返回值

Chromium 的代理说明 当天同样从 main 打开,没有记下 commit。和这条脚本有关的几句是:

PAC 里的写法该页对 Chrome 的说明
DIRECT不经过代理
PROXY host:portHTTP 代理。省略端口时,页上给的默认是 80
SOCKS host:port与 SOCKS4 相同。目标名在客户端解析,而且必须是 IPv4
SOCKS5 host:port目标名总在代理一侧解析。只代理基于 TCP 的 URL,不中继 UDP。Chrome 不对 SOCKS5 做认证

页上写明,Firefox 可以用 network.proxy.socks_remote_dns 选择 SOCKS 的解析位置,Chrome 没有对应开关。那个 Firefox 开关见 远程 DNS 关掉时,AI 域名在本地查。分号隔开的多个代理从左向右试。该页的例子是 PROXY proxy1; HTTPS proxy2; SOCKS5 proxy3,失败后才用下一项。

同一页写了隐式绕过:主机名是 localhost,或是链路本地地址的字面量时,请求直接发出。列出的包括 localhost、*.localhost、[::1]、127.0.0.1/8、169.254/16、[FE80::]/10。它还写明:使用 PAC 时,目前没有开关可以关掉这组隐式绕过。登录停在 127.0.0.1 时,不要把这一下理解成脚本返回了 DIRECT。回环地址本身见 回环地址交给代理,请求就离开本机。

自动检测对应 WPAD。该页写 Chrome 的顺序是:先 DHCP 选项 252,再 DNS 里的 wpad。DHCP 这一步只写了 Windows 和 ChromeOS 上的 Chrome;macOS 上的 Chrome 自己不做 DHCP WPAD,但系统设置里可能已经带上发现到的脚本地址。DNS 这一步查询的是不带点的 wpad,会受搜索后缀影响。页上写,后缀若超出你自己的管理范围,可能选中别人控制的 PAC。不要在不信任的网络上打开自动检测来「顺便获得代理」。本文不写如何架设这种脚本。

看 Chrome 实际用了哪一份脚本时,该页让你在 netlog 里筛 PROXY_、PAC_ 或 WPAD_。2026-11-06 没有在浏览器里导出 netlog。

脚本改对了,仍然不是支持地区

ChatGPT Supported Countries 在 2026-11-06 的页眉是 “Updated: 15 days ago”。页面写明,在列出的国家、地区和领土之外访问或提供访问,账号可能被封锁或暂停。当天列表里能看到 Taiwan,没有看到 China、Hong Kong、Macau。名单很长,发布前应再搜索一次。

Anthropic 与 Gemini 的页面当天没有重开,名单不要和这一份合成一张表。连接超时、重置,仍然先按 大陆代理连上后仍失败 记,不要记成 PAC 的拼写问题。

同日两篇仍是草稿,链接要等发布后才有效。Chrome 自己的安全 DNS 在「不走代理、要由浏览器解析名字」时才会成为下一层,见 安全 DNS 不回退时,AI 域名先失败。已经解析出 AAAA、但隧道只有 IPv4 时,见 AI 的 AAAA 可以不进 IPv4 隧道。

公开文件里的法律范围

《关于清理规范互联网网络接入服务市场的通知》(工信部信管函〔2017〕32号)写明,未经电信主管部门批准,不得自行建立或租用专线(含 VPN)等其他信道开展跨境经营活动。2017 年 1 月 24 日的答记者问说明,对象是无国际通信业务经营资质而开展跨境电信业务经营的企业或个人;企业办公自用、向依法设置国际通信出入口局的经营者租用,不在该条针对的范围内。2026-11-06 没有重新打开部委网页,这段沿用该通知和答记者问的公开表述。本文不判断某种个人使用是否违法,也不写规避执法的做法。

一次失败留下的记录

  1. 浏览器用的是手动代理、PAC 地址,还是自动检测。不要只写「开了系统代理」。
  2. 对失败的那个主机名,脚本返回的是 DIRECT、PROXY、SOCKS 还是 SOCKS5,包括端口。
  3. 有没有 HTTP 状态码,或者只有超时。有地区英文就抄下原文。
  4. 同一主机名用 curl 指定 --proxy 时的状态码。两边不同,先不要改账号。

下一次换脚本,用同一个主机名再记这四项。2026-11-06 的函数结果只属于当天读到的那份源码和 Node 22.23.4。