x-content-type-options 实测:27 个首页 15 个发了,值只有 nosniff 一个词可填
x-content-type-options 在 27 个首页里有 15 个发了,值全是 nosniff —— 这个头只有这一个合法值。同一批里 5 个站的 Content-Type 只写到 text/html,在 HTTP 层一个字都没提编码,其中两个站还同时发了 nosniff。

实测 · 2026-09-01 · 27 个首页 · 各请求一次 · X-Content-Type-Options 与 Content-Type
样本 / 口径:2026-08-15 起沿用的同一批 30 个站。2026-09-01 每个首页发一次 GET,桌面 Chrome UA(不是 Googlebot),跟随跳转,不执行 JavaScript。三个站掉出去了:stackoverflow.com 与 medium.com 返回 403,reddit.com 只回了 8,393 字节的空壳。剩 27 个。
27 个首页里有 5 个在 HTTP 这一层完全没说自己是什么编码 —— Content-Type 只写到 text/html 就停了。同一批里 15 个发了 x-content-type-options,值全是 nosniff,因为这个头只有这一个词可填。而这两件事,在其中两个站身上撞到了一起。
怎么测的
每个站一次请求,本机出口在日本大阪。从交付的响应里只读两个字段 —— Content-Type 与 X-Content-Type-Options —— 读完就结束:没有第二次请求,没有绕缓存,也没有跟前几天的结果比。UA 是桌面 Chrome 字符串,所以下面写的是这些服务器交给浏览器的东西。
只请求了首页。没有向任何一个站要过 JSON 接口、XML sitemap、样式表或脚本文件,而那才是类型嗅探真正会发生的地方。这条限制对下面每一句都成立。
Content-Type 的后半句:22 个写了编码,5 个一个字没写
Content-Type 这一行同时干两件事:说明媒体类型,以及(可选地)说明字符编码。27 个站里 22 个两件都做了,发的是 text/html; charset=utf-8;写法大小写混着来,有的站把编码名写成大写有的写成小写。我们把两种写法算作同一种,下面的结论也不依赖某个站选了哪一种。剩下 5 个写完 text/html 就收笔。
| Content-Type 写法 | 站数 | HTTP 层说编码吗 |
|---|---|---|
| text/html; charset=utf-8(含大写写法) | 22 | 说了 |
| text/html | 5 | 没说 |
这 5 个是 about.gitlab.com、astro.build、developer.mozilla.org、www.framer.com、www.wikipedia.org。没有坏。HTML 标准允许文档自己声明编码,文件开头的一个 <meta charset> 就足够结案 —— 那个声明具体落在第几个字节,是我们在网页编码声明位置实测里量过的另一件事。变的是客户端知道事情的顺序:只读响应头的一方,拿到了类型,没拿到编码。
再看 x-content-type-options:15 个发了,值不是选择题
这个头只有一个指令。MDN 的参考页把语法写成孤零零一行 X-Content-Type-Options: nosniff,并且说这个指令会阻止 MIME 类型嗅探,「causing the browser to use the declared Content-Type without examining the response content」(developer.mozilla.org,2026-09-01 读)。所以这 15 个值本身不携带信息,是同一个词出现了 15 次。这个字段唯一的变量就是发不发。
| 发 nosniff(15) | 没发(12) |
|---|---|
| arstechnica.com | about.gitlab.com |
| developer.mozilla.org | astro.build |
| github.com | railway.com |
| linear.app | react.dev |
| news.ycombinator.com | slack.com |
| nextjs.org | substack.com |
| stripe.com | supabase.com |
| techcrunch.com | webflow.com |
| vercel.com | www.netlify.com |
| www.bbc.com | www.notion.com |
| www.cloudflare.com | www.theverge.com |
| www.figma.com | www.wikipedia.org |
| www.framer.com | — |
| www.nytimes.com | — |
| www.wired.com | — |
这个系列量过的响应头,值大多有得吵:一个 max-age 秒数、一串策略、一份来源白名单。这个头是个勾选框。所以右边那 12 个是一个格外干净的信号 —— 没有人是「设弱了」,因为根本没有弱档可设。12 个团队只是从来没加过这一行。
两个站一边说别猜类型,一边把编码丢出去让人猜
把两列交叉,有两个站同时站在两边。它们各自发了 nosniff,也就是要求浏览器认下声明的类型、别去翻字节;同时它们的 Content-Type 又在编码之前就停了。
| 站点 | Content-Type | 发 nosniff 吗 |
|---|---|---|
| developer.mozilla.org | text/html | 发了 |
| www.framer.com | text/html | 发了 |
| about.gitlab.com | text/html | 没发 |
| astro.build | text/html | 没发 |
| www.wikipedia.org | text/html | 没发 |
这不是 bug。一条指令说别推断类型,同一行又把编码交出去让人从文档里推断。两个字段通常不是同一批人在同一个时间设的 —— 一个来自某次安全评审,一个来自服务器默认配置,两边都没读过对方那半句。
nosniff 是个开关,不是个档位。这一行里还值得读的,是分号后面那半句。
放到同一批站的其它安全头里比一下
同样 27 个站、同样一次请求、同一天。只数发没发,不看值:
| 响应头 | 发了的站数 |
|---|---|
| strict-transport-security | 24 |
| content-security-policy | 17 |
| x-frame-options | 16 |
| x-content-type-options | 15 |
| referrer-policy | 14 |
| permissions-policy | 5 |
| cross-origin-opener-policy | 3 |
15 把它放在中间,比同一批、同一个下午量到的 strict-transport-security 少 9 个站。表里排在它下面的那几个头都需要真去想配置怎么写,靠下的那几个配错了还能把页面弄坏。这一个是一句定死的字符串,加了也弄不坏它贴着的页面。那 9 个站的差距,才是这张表里不好解释的部分。
独立站要做的三件事
三步,第一步是一条命令,而且两个字段一起看得到。
- 跑
curl -sI https://你的域名/ | grep -i content-type。两个字段名里带着同一串字符,一次 grep 就把媒体类型、编码和那行 nosniff 一起打出来。 - 看
text/html后面还有没有东西。如果这行到此为止,你的编码是在文档里声明的,那个声明落在第几个字节就开始要紧了。 - 那行 nosniff 缺了就补上。只有一个值可填,补完也没有后续调参。补它是为了你这个域名发出去的各类文件,别指望它出现在任何搜索报告里。
这一整件事都不动排名,这篇也不打算暗示它动。一个把 HTML 取回去读的爬虫,本来就按你声明的 Content-Type 处理,它一开始就没在猜 —— 所以叫它别猜,改变不了它的任何行为。真正排在所有这些头上游的,是这次抓取能不能成功,那是 AI 爬虫可达性检测在报的事,而它的手工版本写在怎么自查 AI 爬虫能不能抓到你的站里。
这次没测出来的几件事
三条缺口,第一条正好盖住了这个头的本职工作。
- 只请求了首页。没请求过 JSON、XML sitemap、样式表、脚本文件 —— 那才是媒体类型写错或缺失会让浏览器去猜的地方。所以 nosniff 在那 15 个站上到底起了什么作用,这份数据里一点都看不到。
- UA 是桌面 Chrome,也没有在任何一个站上做过「加了这个头之后收录有没有变化」的前后对照。它会不会影响收录,我们不知道;一个首页一次请求,本来也测不出这件事。
- 一次请求、一个出口、一个时刻。机器在大阪,一个会按地域切响应头的 CDN,在这里只会呈现为一个固定事实。
常见问题
你们是怎么测的?
2026-09-01 从大阪对每个首页发一次 GET,桌面 Chrome UA,跟随跳转,不执行 JavaScript,从交付的响应里读 Content-Type 与 X-Content-Type-Options。30 个站里 27 个回了有效结果。
nosniff 到底管什么?
它让浏览器直接采用声明的 Content-Type,不去检查响应内容 —— 按 MDN 参考页 2026-09-01 读到的写法。实际最要紧的是样式表和脚本:类型声明错了,浏览器会直接把文件挡掉。
这个头对 SEO 有帮助吗?
没有。这次测的东西看不到任何关联,机制上也说不通:一个取走你 HTML 的爬虫,用的就是你声明的类型。这 27 个站里有 12 个不发这个头,www.wikipedia.org 和 www.theverge.com 都在其中。
我的 Content-Type 没写 charset,要紧吗?
单看这一条不要紧。这批面板上有 5 个站同样没写,各处渲染都正常,因为编码是在 HTML 里声明的。只有当文档内的那个声明也出现得太靠后,才会真的出事。
除了 nosniff 还能填别的值吗?
没有别的值有用。MDN 参考页上的语法就是一行、一个指令,所以要决定的只有发不发这一行;这批里 15 个发的站,写法完全一样。


