代理、PAC 和 401/407 登录认证怎么处理?
考察点
- 企业网络里“浏览器能上、应用不能上”
session.setProxy和login事件的分工
参考答案
1. 系统代理默认谁在走
渲染进程的请求和主进程的 net 模块走 Chromium 网络栈,会读系统代理和 PAC。Node 的 fetch / http 不读系统代理。企业里 PAC 很常见,业务请求放在 net 或渲染进程,不要放在裸 Node。
2. 按 session 覆盖代理
await session.defaultSession.setProxy({
mode: 'pac_script',
pacScript: 'https://proxy.example.com/proxy.pac',
});
// 或固定代理
await session.defaultSession.setProxy({
proxyRules: 'http=http://127.0.0.1:8888;https=http://127.0.0.1:8888',
proxyBypassRules: 'localhost,127.0.0.1',
});
proxyBypassRules 必须包含本机地址,否则连本地服务也会被送进代理。不同 partition 的 session 要分别设置,改默认 session 不会自动改 persist:account。
3. 代理要求账号密码
HTTP 407 或目标站 401 会走到 login 事件。不处理的话请求一直挂起。
app.on('login', (event, webContents, _details, authInfo, callback) => {
event.preventDefault();
if (authInfo.isProxy) {
// 从 safeStorage 里取出用户填过的代理账号,不要写死在代码里
callback(proxyUser, proxyPassword);
return;
}
callback(); // 不提供凭据,请求按失败结束
});
连续失败要计数,否则错误密码会把 login 打成循环。账号框只在第一次弹出。
4. 和本地抓包工具
开发时可以把代理指到 Charles / Fiddler,同时会遇到自签证书。证书问题走 certificate-error,不要为了抓包把生产环境的校验关掉。
面试话术
系统代理和 PAC 只有 Chromium 网络栈会自动吃,所以业务请求用 net 或页面 fetch。Node 请求要自己处理代理。覆盖代理用 session.setProxy,并绕过 127.0.0.1。代理弹认证时监听 app 的 login,isProxy 为真再交账号密码,失败要限次数。
常见追问
- SOCKS 怎么配?
proxyRules写成socks5://127.0.0.1:1080。PAC 里返回 SOCKS 时由 Chromium 执行脚本,不要自己解析 PAC。 - utilityProcess 的请求走代理吗? 默认不一定走应用 session。需要时在 fork 选项里指定 session。