Playwright143 彻底解决HTTP自动升级HTTPS 解决方案
一、问题背景(精准定位根因)
- 现象描述
Playwright 1.43 版本(内置 Chromium 143 内核)存在顽固问题:
- 手动输入 http://xxx,第一次网络请求直接被浏览器内核篡改为 https
- 无服务器 301/302 重定向、无页面 JS 跳转、无 CSP 头、无 HSTS 缓存
- 常规移除 upgrade-insecure-requests 请求头完全无效
- 旧版禁用参数 AutoUpgradeInsecureRequests 新版彻底失效
- 真实根因(核心关键)
Chromium 117+ 新版内核新增 HttpsUpgrades 底层强制升级机制:
浏览器网络内核层在请求发出前,直接强制将 HTTP 协议升级为 HTTPS,属于内核硬编码行为。
该行为发生在:页面加载前、JS执行前、请求拦截前
✅结论:JS、页面拦截、改请求头全部无效,只能通过内核启动参数关闭
二、新旧方案失效原因(避坑必看) - 无效方案(全网大部分旧教程)
- 移除 upgrade-insecure-requests 请求头:只能解决页面二次升级,无法解决内核首次劫持
- --disable-features=AutoUpgradeInsecureRequests:143 版本已废弃,完全无效
- 禁用 HSTS、忽略证书错误:无法阻止内核主动协议篡改
- 前端 JS 拦截、location 跳转修复:请求早已发出,为时已晚
- setMaxRedirects(0):仅拦截服务器重定向,无法拦截内核主动升级
- 唯一有效核心参数(143版本专属)
--disable-features=HttpsUpgrades
作用:彻底关闭 Chromium 内核底层自动 HTTP→HTTPS 强制升级机制(根治首次请求篡改问题)
三、最终完整生产级配置(100%生效) - 完整启动参数组合(最优、无冗余、无冲突)
启动参数
作用说明
--disable-features=HttpsUpgrades
核心必杀:关闭内核首次HTTP强制升级HTTPS(解决你的核心问题)
--no-https-first-mode
关闭HTTPS优先模式,兜底防止二次升级
--ignore-certificate-errors
忽略HTTP页面证书报错,保证正常访问
--allow-running-insecure-content
允许HTTP不安全资源加载 - 请求头兜底处理
关闭内核升级后,再移除浏览器默认携带的 upgrade-insecure-requests 头,彻底干净。
四、最终完整可运行 Java 代码(生产可用)
适配:Playwright 1.43 、Chromium 143、Java 8+
import com.microsoft.playwright.*;
import java.util.HashMap;
import java.util.Map;
/**
-
Playwright143 彻底禁止HTTP自动升级HTTPS 最终解决方案
-
解决:内核首次请求强制篡改http->https 问题
*/
public class PlaywrightHttpStableFix {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {// 【核心内核配置 100%生效】禁用Chromium143底层HTTPS自动升级 Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions() .setHeadless(true) // 生产环境无头模式 .setArgs(java.util.Arrays.asList( // 必杀核心参数:关闭内核Https自动升级(解决首次请求篡改) "--disable-features=HttpsUpgrades", // 兜底关闭HTTPS优先模式 "--no-https-first-mode", // 允许不安全内容、忽略证书错误 "--allow-running-insecure-content", "--ignore-certificate-errors" )) ); // 上下文全局忽略HTTPS错误 BrowserContext context = browser.newContext(new Browser.NewContextOptions() .setIgnoreHTTPSErrors(true) ); Page page = context.newPage(); // 兜底拦截:移除所有升级相关请求头,彻底干净 context.route("**/*", route -> { Map<String, String> headers = new HashMap<>(route.request().headers()); // 移除浏览器默认自动添加的升级头 headers.remove("upgrade-insecure-requests"); headers.remove("Upgrade-Insecure-Requests"); route.resume(new Route.ResumeOptions().setHeaders(headers)); }); // 监听所有网络请求,验证是否纯HTTP page.onRequest(request -> { System.out.println("请求地址:" + request.url()); }); // 访问HTTP地址(不会再自动跳HTTPS) page.navigate("http://xxx.com"); System.out.println("最终页面地址:" + page.url()); // 关闭资源 page.close(); context.close(); browser.close(); } catch (Exception e) { e.printStackTrace(); }}
}
五、效果验证标准
满足以下三点即为彻底解决:
- 首次网络请求 无 https 篡改
- 请求头中 无 upgrade-insecure-requests
- 页面最终 URL 保持 http:// 协议
六、关键知识点总结(独家踩坑结论) - 问题层级
- 301重定向:应用层跳转 → 可通过代码拦截
- 请求头升级:页面层控制 → 可删除Header解决
- 内核HttpsUpgrades:网络内核层硬编码 → 仅能通过启动参数关闭
- 版本适配说明
--disable-features=HttpsUpgrades
- 适配:Chromium 117+ / Playwright 1.40+ 新版本
- 旧参数 AutoUpgradeInsecureRequests 新版彻底废弃、无效
- 为什么JS完全无效?
内核协议篡改发生在:网络请求阶段
JS执行发生在:页面渲染完成阶段
顺序:内核改协议发请求 → 等待响应 → 加载页面 → 执行JS,JS完全来不及拦截
七、终极最简生产配置(可直接拷贝上线)
只保留必须生效参数,无任何冗余、无冲突:
new BrowserType.LaunchOptions()
.setArgs(java.util.Arrays.asList(
"--disable-features=HttpsUpgrades",
"--no-https-first-mode",
"--ignore-certificate-errors"
))
八、最终结论(一句话总结)
Playwright143 浏览器首次请求自动HTTP变HTTPS,是 Chromium 新版内核 HttpsUpgrades 机制导致,唯一解决方案:添加启动参数 --disable-features=HttpsUpgrades,配合移除升级请求头,可100%彻底根治。