Chrome无头模式配合BrowserMob Proxy返回空HTML响应,如何解决?
BrowsermobProxy适配Chrome无头RemoteDriver白屏问题解决方案
问题背景
使用BrowsermobProxy抓取UI自动化测试的网络日志,需同时适配有头、无头两种RemoteDriver模式,有头模式运行正常,无头模式出现白屏问题。
有头Remote Driver代码
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(browserMobProxy); seleniumProxy.setNoProxy("<-loopback>"); seleniumProxy.setHttpProxy("localhost" + ":" + browserMobProxy.getPort()); seleniumProxy.setSslProxy("localhost" + ":" + browserMobProxy.getPort()); desiredCapabilities = DesiredCapabilities.chrome(); desiredCapabilities.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE); desiredCapabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, Boolean.TRUE); desiredCapabilities.setAcceptInsecureCerts(Boolean.TRUE); desiredCapabilities.setJavascriptEnabled(Boolean.TRUE); ChromeOptions options = getChromeOptions(driverConfig.getUserAgent(), Boolean.TRUE); options.setCapability(CapabilityType.PROXY, seleniumProxy); desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options); desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options); return RemoteWebDriver(remoteAddress, desiredCapabilities)
无头Remote Driver原始代码
ChromeOptions options = new ChromeOptions(); options.addArguments("--user-agent=" + "HeadlessChrome"); options.setAcceptInsecureCerts(Boolean.TRUE); options.setHeadless(true); options.addArguments("--allow-insecure-localhost", "--no-sandbox", "--disable-extensions", "--window-size=1920,1080"); options.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true); List<String> optionsArg = ImmutableList.of("--ignore-certificate-errors", "--proxy-bypass-list=<-loopback>", "--proxy-server=http://localhost:" + mobProxy.getPort(), "--remote-debugging-port=9222"); options.addArguments("--ssl-protocol=any"); options.addArguments("--allow-running-insecure-content"); options.addArguments(optionsArg); capabilities.setCapability(ChromeOptions.CAPABILITY, options); driver = new RemoteWebDriver(driverUrl, capabilities);
无头模式驱动配置
- Driver URL -> http://localhost:<port_number> [示例: http://localhost:29515]
- BrowserMob Proxy端口 -> <dynamic_port> [示例:33173]
- 代理服务器地址 -> http://localhost:<dynamic_port> [示例: http://localhost:33173]
无头驱动创建前完整能力配置
{acceptInsecureCerts=true, acceptSslCerts=true, browserName=chrome, goog:chromeOptions={args=[--user-agent=HeadlessChrome, --headless, --disable-gpu, --allow-insecure-localhost, --no-sandbox, --disable-extensions, --window-size=1920,1080, --ssl-protocol=any, --allow-running-insecure-content, --ignore-certificate-errors, --proxy-bypass-list=<-loopback>, --proxy-server=http://localhost:33173, --remote-debugging-port=9222], extensions=[]}, platform=ANY, version=}
运行结果
测试失败时截图仅显示白屏,已配置页面加载隐式等待,额外添加5秒静态等待也无法解决,获取到的HTML内容为:
<html><head></head><body></body></html>
已知信息
- 尝试过设置参数
--proxy-bypass-list=*,此时页面可以正常加载,但网络请求不会经过mob proxy,无法录制到日志。 --ssl-protocol=any、--remote-debugging-port=9222、--allow-running-insecure-content为额外添加的配置,移除后问题依然存在。- 使用的版本为:browser-mob-proxy = 2.1.5;ChromeDriver版本 = 92.0.4515.159
- 运行环境为远程Linux CLI系统
- Browsermob Proxy原始启动配置如下:
System.setProperty("bmp.allowNativeDnsFallback", "true"); BrowserMobProxy browserMobProxy = new BrowserMobProxyServer(); browserMobProxy.setTrustAllServers(Boolean.TRUE);
修复方案
1. 调整BrowsermobProxy启动配置,允许外部访问
BMP默认绑定本地回环地址,远程Chrome节点无法访问,启动时绑定所有网卡:
System.setProperty("bmp.allowNativeDnsFallback", "true"); BrowserMobProxy browserMobProxy = new BrowserMobProxyServer(); browserMobProxy.setTrustAllServers(Boolean.TRUE); // 绑定0.0.0.0允许所有网卡访问,0表示自动分配可用端口 browserMobProxy.start(0, InetAddress.getByName("0.0.0.0"));
同时放开远程Linux环境对应端口的防火墙规则,允许Chrome节点访问BMP端口。
2. 代理地址替换为对外可访问IP
不要使用localhost作为代理地址,替换为BMP所在机器的内网/公网可访问IP,比如BMP部署在IP为192.168.3.20的机器上,代理地址写为http://192.168.3.20:<BMP端口>。
3. 统一代理配置方式,新增Chrome适配参数
无头模式的代理配置和有头模式保持一致,使用Selenium Proxy对象注入,避免直接配置Chrome参数导致的冲突,同时新增适配参数解决Chrome 92版本无头模式白屏问题:
ChromeOptions options = new ChromeOptions(); options.addArguments("--user-agent=HeadlessChrome"); options.setAcceptInsecureCerts(Boolean.TRUE); options.setHeadless(true); // 新增解决白屏参数 options.addArguments("--disable-features=VizDisplayCompositor"); options.addArguments("--allow-insecure-localhost", "--no-sandbox", "--disable-extensions", "--window-size=1920,1080", "--ignore-certificate-errors"); // 和有头模式保持一致,用Selenium Proxy对象配置代理 Proxy seleniumProxy = ClientUtil.createSeleniumProxy(browserMobProxy); // 替换为BMP的对外IP String proxyAddr = "192.168.3.20:" + browserMobProxy.getPort(); seleniumProxy.setHttpProxy(proxyAddr); seleniumProxy.setSslProxy(proxyAddr); options.setCapability(CapabilityType.PROXY, seleniumProxy); options.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true); capabilities.setCapability(ChromeOptions.CAPABILITY, options); driver = new RemoteWebDriver(driverUrl, capabilities);
4. 网络连通性验证
先登录远程Chrome节点所在机器,执行curl -x http://<BMP_IP>:<BMP_PORT> 被测页面地址,确认可以正常获取页面内容,再执行自动化用例。
内容的提问来源于stack exchange,提问作者Dipan Biswas
相关产品推荐
相关产品推荐

