如果 Jint 在求值 PAC 时报告缺少 dnsResolve 或 myIpAddress,再加载更多 JavaScript 未必是解决办法。这些 PAC 辅助函数属于宿主应用提供的运行环境。

调用 FindProxyForURL 之前

先选定支持的 PAC 辅助函数集合与地址族,再把这些辅助函数安装到引擎上。要保持它们的契约:dnsResolve 接收主机名,myIpAddress 不接收参数且需要本地接口策略,shExpMatch 使用 shell 风格的模式。返回一个方便值的桩实现可能悄悄选错路由。

完成这些初始化后,Jint 4.4.0 中的核心调用可以写成这样:

var destination = new Uri(destinationUrl);
engine.Execute(pacSource);
var routeList = engine.Invoke(
    "FindProxyForURL",
    destinationUrl,
    destination.IdnHost
).AsString();

engine 是配置好的 Jint.Engine;pacSource 是获取到的 PAC 程序。destination.IdnHost 提供不带端口和路径的主机名。这个调用既不获取 PAC,也不打开代理连接。

调用之后

把 PROXY proxy.example:8080; DIRECT 这样的结果解释为按顺序排列的候选路由与兜底列表。把整个字符串当作代理 URL 传入会丢失其含义。要把求值失败与明确的 DIRECT 结果区分开。

运行期间

配置 Jint 的时长、语句、内存与取消限制,并且只暴露必需的宿主函数。DNS 回调要单独设限:JavaScript 执行检查并不会让任意阻塞的宿主调用变得可中断。对同一个引擎的访问要串行化,或者让并发工作使用各自独占的实例;引擎不适合同时使用。

浏览器的 PAC 实现在辅助函数扩展和所暴露的 URL 细节上可能不同,HTTPS 尤其如此。与一个样例结果相符,并不等于与浏览器的路由行为相符。

相关文章