技术复盘文档:HTTPS 站点安全下载 HTTP 资源实践总结

0 阅读3分钟

技术复盘文档:HTTPS 站点安全下载 HTTP 资源实践总结

1. 业务背景

子系统日志中心 业务模块中,用户需要从主站界面下载各子系统的运行日志(如 ETL 日志、DCP 日志)。

  • 主站域名https://aims.dcsoft.localhttps://083.dev.aims.dcsoft.vip (安全 HTTPS 协议)
  • 下载服务器http://192.168.13.220:2800http://192.168.100.72:2800 (非安全 HTTP 协议)
  • 资源类型.log 后缀的文本文件
  • 核心诉求:点击下载按钮后,触发文件下载,严禁导致主站页面跳转或重定向

2. 核心问题描述

由于现代浏览器(尤其是 Chrome 88+)加强了安全防护,当一个 HTTPS 站点 尝试请求一个 HTTP 资源 进行下载时,会触发 Mixed Content(混合内容) 拦截和 Insecure Download Blocking(不安全下载拦截)

其表现为:浏览器认为该下载不安全,为了提醒用户,会强行夺取主站窗口的控制权并将其重定向到目标地址,导致主站业务中断。

3. 技术探索历程与失败原因分析

我们针对该问题先后尝试了 6 种前端方案,均由于浏览器底层的安全策略无法完美达成目标:

方案一:动态 <a> 标签 + download 属性

  • 操作:创建隐藏 <a> 标签,设置 target="_blank"download 属性
  • 结果:主站重定向跳转,下载未触发
  • 原因download 属性在跨域/跨协议时被浏览器忽略。Chrome 识别到安全降级,强行在当前窗口导航

方案二:隐藏 <iframe> 方案

  • 操作:创建不可见 iframe,将其 src 指向下载地址
  • 结果:控制台报错:was loaded over an insecure connection
  • 原因:Mixed Content 拦截。HTTPS 严禁以 Frame 形式加载 HTTP 资源

方案三:window.open('about:blank') + document.write 中转

  • 操作:先开空白页,在新页内注入跳转脚本
  • 结果:主站依然闪退/跳转,或者新页面无反应
  • 原因:Chrome 会追踪窗口的 opener(血缘关系)。只要新窗口处于主站的安全上下文中,不安全下载依然会触发父窗口的关联重定向

方案四:window.open + noopener noreferrer

  • 操作:彻底斩断新旧窗口的联系
  • 结果:主站保住了,但新窗口打开后显示日志文本,不触发下载;或弹出"您即将提交的信息不安全"的蓝色警告页
  • 原因
    • 蓝色警告是 Chrome 对跨协议提交的硬件级拦截,JS 无法消除
    • .log 被识别为文本,后端缺少 Content-Disposition 响应头,导致预览而非下载

方案五:Form 表单提交到 target="_blank"

  • 操作:创建隐藏表单模拟 POST/GET 提交
  • 结果:跳转到新窗口,但必现"您即将提交的信息不安全"提示
  • 原因:浏览器判定将加密页面的数据提交到非加密页面存在风险

4. 根源复盘总结

4.1 为什么前端无法完美解决?

浏览器厂商(Google/Microsoft)已经将 "HTTPS 页面静默触发 HTTP 下载" 这条路在代码层面封死了。

  • 如果使用 脚本触发,浏览器判定为流氓行为,直接重定向主站
  • 如果使用 用户点击,浏览器判定为安全降级,弹出蓝色警告提示

4.2 为什么手动复制链接可以下载?

因为手动复制链接属于 "用户在地址栏直接输入",不属于任何站点的派生行为,浏览器不执行混合内容检查。