PAYATHON 2026

Google Chrome 访问 Pay Deposit 页面提示 insecure

支付老李

结论

这是典型的 Mixed Content(混合内容) 问题。Pay Deposit 页面通过 HTTPS 打开,但表单、脚本、iframe、弹窗地址或某次重定向仍在访问 HTTP URL。Chrome 阻止请求后,支付流程无法继续,页面因此只显示主菜单或空白区域。

报错中最值得关注的是:

http://linkurl/404/

不要只检查页面直接引用的两个 include 文件,还要查清支付请求为什么最终进入 HTTP 的 /404/。原因可能是支付地址错误、相对路径解析异常、HTTP 重定向,或者站点的 404 错误处理程序把 HTTPS 请求降级成了 HTTP。

排查步骤

1. 用 Chrome DevTools 找出第一个异常请求

打开开发者工具,进入 Network 面板:

  1. 勾选 Preserve log。
  2. 清空现有记录。
  3. 重新执行 enrollment,然后点击 Pay Deposit。
  4. 搜索 http://、404,或者筛选状态码为 3xx、4xx 的请求。
  5. 查看异常请求的 Initiator、Headers 和重定向链。

需要确认:

  • 最初请求的 URL;
  • 发起请求的页面或脚本;
  • 请求是否先访问 HTTPS,随后被 Location 响应头重定向到 HTTP;
  • /404/ 是直接请求的地址,还是服务器处理错误时跳转过去的。

Console 中的 mixed-content 报错通常只显示最终被阻止的 URL。Network 面板中的发起者和重定向链更适合追查问题源头。

2. 检查支付流程中的所有 URL

除了 <script> 和 <link>,还要检查这些位置:

<form action="http://example.com/pay">
<iframe src="http://example.com/pay">
<script src="http://example.com/payment.js"></script>
<link rel="stylesheet" href="http://example.com/payment.css">
<img src="http://example.com/logo.png">
<base href="http://example.com/">

JavaScript 也可能动态发起不安全请求:

window.open("http://example.com/pay");
location.href = "http://example.com/pay";
fetch("http://example.com/api/deposit");

如果支付按钮位于弹窗中,尤其要检查:

  • window.open() 的目标地址;
  • 表单的 action 和 target;
  • iframe 的 src;
  • AJAX 请求返回的跳转地址;
  • 服务端生成的支付 URL;
  • <base> 标签是否把相对路径解析成了 HTTP。

3. 将内部地址改为 HTTPS 或站内相对地址

同一站点内的资源优先使用根相对路径:

<form action="/pay/deposit" method="post">
  <!-- payment fields -->
</form>

<script src="/assets/payment.js"></script>
<link rel="stylesheet" href="/assets/payment.css">

必须使用绝对地址时,明确指定 HTTPS:

<form action="https://example.com/pay/deposit" method="post">

JavaScript 中也应采用相同方式:

window.open("/pay/deposit", "payDeposit");

不建议把协议相对 URL 作为长期修复方案:

<script src="//example.com/payment.js"></script>

这种地址通常会继承当前页面的协议,但明确使用 HTTPS 或站内相对路径更便于审计,也不会在非预期环境中回落到 HTTP。

4. 修复重定向和 404 页面配置

如果初始地址已经使用 HTTPS,但响应中出现:

Location: http://example.com/404/

问题出在服务端,而不是 HTML include 文件。重定向也应保持 HTTPS:

Location: https://example.com/404/

通常更合适的做法是直接返回正确的 404 状态和错误页面,不再跳转到另一个 URL:

HTTP/1.1 404 Not Found
Content-Type: text/html; charset=utf-8

同时检查:

  • Web 服务器的 rewrite/redirect 规则;
  • 应用中的 canonical URL、base URL 或 site URL 配置;
  • 反向代理传递的原始协议;
  • 404、登录和支付失败处理代码;
  • 支付服务的回调地址和返回地址。

如果应用部署在负载均衡器或反向代理之后,外部连接可能使用 HTTPS,而应用服务器看到的却是 HTTP,应用便可能错误地生成 http:// URL。此时需要正确传递并验证原始协议,例如:

X-Forwarded-Proto: https

信任代理的具体配置取决于所使用的 Web 框架。不要在未限制可信代理来源时,直接信任客户端提供的 X-Forwarded-Proto。

5. 确认第三方支付服务支持 HTTPS

如果 http://linkurl 属于第三方支付服务,需要确认该服务提供有效的 HTTPS 接口。不能直接把 URL 中的 http: 改成 https:,因为对方服务器可能没有配置 HTTPS、有效证书或对应路由。

如果第三方资源没有 HTTPS 版本,就不能安全地嵌入 HTTPS 支付页面。可以选择:

  • 使用该服务提供的 HTTPS 地址;
  • 升级支付接口;
  • 更换支持 HTTPS 的支付服务;
  • 在支付服务明确支持的情况下,使用其官方托管支付页流程。

关闭 Chrome 的安全设置不能解决生产环境中的问题,只会在本机掩盖风险,其他用户仍会遇到请求被阻止的情况。

可增加的安全配置

修复所有 HTTP 引用后,可以添加 Content Security Policy,用于发现遗漏的资源或尝试将其升级:

Content-Security-Policy: upgrade-insecure-requests; block-all-mixed-content

也可以先启用仅报告模式进行观察,以免立即影响线上功能:

Content-Security-Policy-Report-Only: upgrade-insecure-requests

upgrade-insecure-requests 会尝试把 HTTP 子资源升级为 HTTPS,但无法处理以下问题:

  • 目标服务器不支持 HTTPS;
  • HTTPS 路径不存在;
  • 证书无效;
  • 应用在重定向后再次降级到 HTTP;
  • URL 指向错误路径,并最终进入 /404/。

因此,CSP 只能作为补充,不能代替修复实际链接和服务端配置。

确认整个站点能够稳定通过 HTTPS 工作后,还可以考虑启用 HSTS:

Strict-Transport-Security: max-age=31536000; includeSubDomains

启用 includeSubDomains 前,需要确认所有子域名都支持 HTTPS,否则可能导致部分子域名无法访问。

为什么其他浏览器正常

其他浏览器能显示页面,不代表页面配置没有问题。不同浏览器和不同版本对 mixed content 的拦截策略可能不同。旧浏览器可能继续加载不安全内容,而 Chrome 会阻止影响页面逻辑的脚本、iframe、表单或请求。

支付页面涉及账户和交易数据,不能依赖浏览器放宽安全限制。修复后的标准应该是:从点击 Pay Deposit 按钮开始,直到支付页面、接口请求、错误处理和重定向结束,整个请求链都使用有效的 HTTPS,并且不再生成任何 http:// 子资源。

备注:内容仅供参考。