惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
P
Proofpoint News Feed
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
Microsoft Security Blog
Microsoft Security Blog
F
Fortinet All Blogs
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
美团技术团队
D
Docker
博客园 - Franky
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

博客园 - e3tB8Wz7

鼠标连选问题排查与解决 Vue 3 + Vite 生产构建下自定义弹窗组件大面积失效:根因排查与修复实录 Windows PowerShell 查看特定网卡的详细信息 阿里云 CentOS 7 yum镜像(Centos-7.repo) powershell上移文件夹下的所有文件 一行命令查看docker所有网络 + 子网 nginx配置文件生产环境优化 Microsoft Office 安装与激活 Microsoft Edge隐藏边栏快捷键 微信小程序hideLoading隐藏showToast提示的问题 前端开发解决方案 pl/sql developer设置oracle环境变量 postman-app下载官方历史版本 logback日志格式 springboot alibaba druid数据库连接池配置,输出可执行sql 统计accesslog日志中的慢接口,排序后取前几条 将多个文件的内容附加到一个文件中 统计accesslog日志中每个url的请求次数,排序后取前几条 如何在反向代理后面部署spring服务? Shell:用sed命令删除特定行 Git for Windows 国内下载站 oracle查询日期属于一年的第几周,日期所在周的周一是哪一天
一行代码解决 Chrome 对 HTTP 站点 Office 文件的下载拦截
e3tB8Wz7 · 2026-07-29 · via 博客园 - e3tB8Wz7

Chrome 拦截 HTTP 站点的文件下载?一行代码改掉它的判断逻辑

问题:用户点导出,Chrome 弹"不安全"

一个内网系统通过 HTTP 提供服务,导出功能生成 .docx 文件。Chrome 每次下载都弹:

此文件可能不安全/可能已被篡改

非技术用户不敢点"保留",以为系统坏了。

排查:代码明明已经用 Blob 下载了

前端代码是这样写的:

// API 层:用 responseType: 'blob' 获取二进制
const response = await request.download({ url: '/api/report/export' })

// 前端层:提取文件名,用 Blob URL 触发下载
download.word(response.data, fileName)

download.word() 内部走的就是 URL.createObjectURL(blob) + <a download> 点击。早就不是浏览器原生下载了——为什么还拦?

后来发现,Chrome 的判断不看下载方式,看服务器说了什么

根因:一个 HTTP 头引发的拦截

后端 Controller 是这样写响应头的:

response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setHeader("Content-Disposition", "attachment; filename=\"工作周报.docx\"");

Chrome 的处理链:

响应头含 Content-Disposition: attachment
  → Chrome 判定:"这是个要下载的文件"
  → 检查:来源是 HTTP?
  → 检查:文件类型在危险名单里?(docx ✅、zip ✅、exe ✅)
  → 弹警告

Content-Disposition: attachment 就是触发 Chrome 下载安全检查的开关。 你关掉它,Chrome 就不再走那条检查链路。

我们试过的三个方案

方案 A:搭 HTTPS(失败)

  • 给测试服务器绑了 mkcert 自签证书
  • 每个开发者/用户都要手动装根证书
  • 非技术用户:"什么叫证书?怎么装?"
  • 放弃

方案 B:data: URI 下载(未遂)

想把 Blob 读成 base64,用 data:application/vnd... 格式触发下载,绕过 HTTP 来源追踪。

data: URI 对大文件不友好(base64 编码膨胀 33%),且逻辑上还是在绕安全机制,不够干净。

方案 C:让服务器闭嘴(成功)

核心思路:既然 Content-Disposition: attachment 是你拦截的判断依据,那我就不发这个头。

文件内容照样传、文件名照样给、下载照样触——只是"这是下载文件"这句话不让服务器说,改由 JS 说。

最终方案:一行改动的全部代码

后端

// 改前
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

// 改后——去掉 Content-Disposition: attachment
response.setHeader("X-Filename", URLEncoder.encode(fileName, StandardCharsets.UTF_8));

前端

// 改前
const disposition = response?.headers?.['content-disposition'] || ''
const match = /filename\*=UTF-8''([^;]+)/i.exec(disposition)
fileName = match ? decodeURIComponent(match[1]) : fallback

// 改后——优先读 X-Filename,兼容旧版 Content-Disposition
const xFilename = response?.headers?.['x-filename'] || ''
if (xFilename) {
  fileName = decodeURIComponent(xFilename)
} else {
  // 兼容旧版
  const match = /filename\*=UTF-8''([^;]+)/i.exec(response?.headers?.['content-disposition'] || '')
  if (match) fileName = decodeURIComponent(match[1])
}

改完部署,用户点导出——不弹警告了。

为什么这样能绕过 Chrome?

改前流程:
  服务器 → 浏览器:"接住,这是个要下载的 .docx 文件"
  浏览器 → "HTTP 来的 .docx?不安全!" → 弹警告

改后流程:
  服务器 → 浏览器:"这是数据流"(没有 attachment 头)
  JS     → 浏览器:"帮我把这段数据保存为文件"(Blob URL + <a download>)
  浏览器 → "JS 让我存数据,不管来源"  → 正常下载

Chrome 不会对 JS 发起的 Blob URL 下载做安全检查——那是用户代码的行为,不是网络层的文件传输。

意外发现:为什么 Excel 不弹警告?

测试过程中发现,同系统的 Excel 导出从不触发警告。看了代码,Excel 和 Word 用的是完全相同的下载链路(responseType: 'blob' + URL.createObjectURL)。

最后查 Chrome 源码确认:Chrome 对 .docx.xlsx 的安全策略不同。 .docx 历史上是宏病毒的常见载体,被列为"高风险"类型;.xlsx 虽然也在危险名单里,但 Chrome 的拦截阈值对 Word 文档更严格。

如果你的系统同时有 Excel 和 Word 导出,别奇怪——不是你代码的问题,是 Chrome 的区别对待。

一句话总结

不要让服务器对 Chrome 说"这是下载文件"(Content-Disposition: attachment)。让 JS 自己下载。Chrome 不拦自己人。

适用场景

  • 内网 HTTP 站点导出 Office 文档(.docx.xlsx.pptx
  • 导出 ZIP 压缩包
  • 任何 Chrome 标记为"不安全下载"的 HTTP 文件传输

局限性

这个方案的本质是绕过 Chrome 的检查,不是修复 HTTP 的安全问题。如果你的系统面向公网或有合规要求,长期方案仍然是上 HTTPS + 域名 + 公网 CA 证书。