X-Content-Type-Options

X-Content-Type-Options:nosniff 防止浏览器对响应内容进行 MIME 嗅探,强制按 Content-Type 声明处理。

#type / concept #status / evergreen #tech / security #resource / http #platform / browser

[!info] related notes

X-Content-Type-Options

一句话定义

X-Content-Type-Options: nosniff 告诉浏览器:不要猜测响应的 MIME 类型,严格按照 Content-Type 声明处理。

它要解决什么问题

浏览器有一种行为叫 MIME sniffing(类型嗅探):当服务器没有明确声明 Content-Type,或者声明的类型和实际内容”看起来不一致”时,浏览器会自己猜测内容类型并按猜测结果处理。

这可能导致安全问题:

服务器声明 Content-Type: text/plain
但响应体内容看起来像 HTML
浏览器猜测它是 HTML 并渲染执行
如果内容中包含恶意脚本 → XSS

核心机制

Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff

设了 nosniff 后:

  • 如果 Content-Typetext/htmlapplication/javascriptimage/* 等已知类型,浏览器严格按声明处理
  • 如果类型不匹配,浏览器直接拒绝,而不是猜测

受影响的场景

浏览器对以下 MIME 类型会做 sniffing 检查(设了 nosniff 后):

  • text/html
  • text/xml
  • application/xml
  • application/javascript
  • image/*

对于 text/plainapplication/octet-stream 等,nosniff 的行为因浏览器而异。

推荐配置

建议常开。几乎所有现代 Web 应用都应该设置:

X-Content-Type-Options: nosniff

单独使用没有意义,必须配合正确的 Content-Type

Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff

常见场景

场景 1:API 返回 JSON 但 Content-Type 写错

# 错误
Content-Type: text/html
X-Content-Type-Options: nosniff

{"error": "not found"}

如果 HTML CSP 不允许 inline script,浏览器可能拒绝渲染这段”HTML”。正确做法是设 Content-Type: application/json

场景 2:用户上传文件被下载时

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="data.csv"
X-Content-Type-Options: nosniff

防止浏览器把用户上传的 CSV 文件当成 HTML 渲染(如果内容中包含恶意 HTML)。

边界与易混淆点

  • nosniff 不是”禁止执行脚本”:它只管类型嗅探,脚本执行由 CSP 控制。
  • nosniff 不影响正常的 Content-Type:如果 Content-Type 正确,nosniff 只是多一层保险。
  • 它是单值头:只有 nosniff 一个有效值,不存在其他选项。
  • 所有主流浏览器都支持:Chrome、Firefox、Safari、Edge 均支持。
创建于 2026/5/24 更新于 2026/5/27