HTTP头信息检查工具
检查任何URL的HTTP响应头信息和安全状况。
🌐 sitekits fetches the URL server-side (private/internal addresses are blocked). Response body is not retrieved.
概述
响应头才是一个站点的行为真正被配置的地方——缓存、压缩、安全策略、CORS、重定向都在这里——而这也恰恰是你不打开 DevTools、不在里面找到正确的那个请求就看不见的部分。
这个工具在服务端请求一个 URL,把它的响应头返回给你,同时附上一路走到那里的完整重定向链。因为浏览器自身的安全模型把跨源响应头对 JavaScript 隐藏了起来,这是本站少数几个无法完全在你自己页面里运行的工具之一。
使用方法
- 输入一个 URL。协议部分可以省略——
example.com会被当作https://example.com来处理。 - 先读重定向链。其中每一跳都会显示它自己的 URL 和状态码。
- 然后再读最终那一份响应头。
重定向链通常就是答案本身
当某个东西慢下来、或者某个规范 URL 不对时,这条链就是你唯一能看见它的地方。每一跳都是一次完整的网络往返,而下面这几种常见的情形其实全都是可以避免的:
http://example.com→https://example.com→https://www.example.com是两次重定向,而一次本来就够了。直接一跳跳到最终的主机和协议。- 站点迁移之后,一个
301落到另一个301上,意味着两代规则都还在生效。 - 重定向到一个又跳回来的 URL 就构成了环;工具在五跳之后停下,而不会跟着它一直绕。
- 你本意是
301却写成了302,那是在告诉爬虫这次搬迁只是临时的,于是旧 URL 保住自己的排名,新 URL 什么也积累不到。
301/302 和 307/308 之间的区别在于请求方法。历史上,客户端在跟随 301 和 302 的时候会把 POST 变成 GET;而 307 和 308 会保留原来的方法。如果一次表单提交在经过重定向之后行为变得很古怪,这就是第一件应该去查的事。
值得仔细读的那些响应头
| 响应头 | 该看什么 |
|---|---|
cache-control | 静态资源上的 no-store 是在浪费带宽;HTML 上一个过长的 max-age 会让发布变得完全看不见 |
etag / last-modified | 它们缺失意味着每一次重新验证都要把整个正文再传一遍 |
content-encoding | 文本响应上缺 gzip 或 br,是你能拿到的最便宜的那份性能收益 |
vary | 一个 Vary: User-Agent 会把每个 CDN 缓存碎片化成上百份副本 |
strict-transport-security | max-age 太短,或者缺了 includeSubDomains,会让第一次请求仍然可以被降级 |
content-security-policy | 各条指令具体是什么含义,见 CSP 生成器 |
x-content-type-options | 没有 nosniff,一个写错的 content-type 就可能被重新解释成脚本 |
access-control-allow-origin | 你的 fetch 失败的原因几乎总在这里,或者就是它根本不存在 |
set-cookie | 凡是携带会话的,都检查一下 Secure、HttpOnly 和 SameSite |
server 和 x-powered-by 值得注意的理由正好相反:它们只是泄露了软件版本,除此之外什么作用都没有。把它们删掉算不上一项真正的安全控制措施,但也确实找不出任何理由继续留着它们。
这个工具刻意不做的事
处理器在建立连接之前,会先把 URL 对照一份包含私有、回环、链路本地和保留地址段的黑名单做校验,并在每一跳重定向上把这个检查重做一遍。没有这个逐跳检查,一个公网主机名就可以重定向到 127.0.0.1 或者某个云元数据地址,而请求会一路跟过去——一个检查响应头的服务,正是这样变成从外部探测别人内网的手段的。
它同样从不转发响应正文。连接只被读取到响应头为止,然后就直接丢掉。一个会返回任意正文的服务就是一个开放代理,不管它当初是不是抱着这个意图做的。
URL 里内嵌的凭据(https://user:pass@host/)在请求发出之前就已经被剥掉了,所以它们既不会被发给目标站点,也不会在重定向链里被回显出来。
示例
- 一个你怎么都复现不了的 CORS 错误。 拿真实端点上的
access-control-allow-origin和你代码所期待的那个值对比一下。响应头缺失和响应头写错,在浏览器里会产生完全相同的一条消息。 - 一次死活出不来的发布。 看 HTML 上的
cache-control和age。CDN 正在提供一个缓存过的文档,这个解释比构建出错要常见得多。 - 审计一次安全响应头的上线。 在线上主机上、而不是在你的配置文件里检查
strict-transport-security、content-security-policy和x-content-type-options,因为 CDN 或 WAF 可能添加、剥离或者覆盖其中的任何一个。 - 验证一次规范重定向。 确认这条链正好只用一跳,就落在你想要的那个主机和协议上。
说明
请求使用一个明确标明本工具身份的固定 User-Agent,并且在五秒之后超时。一个会屏蔽未知代理的站点会回一个 403,那是关于该站点配置的一个真实答案,而不是这里出了什么故障。
响应头名称按服务器发送时的原样显示。HTTP/2 要求在线路上使用小写名称,所以一个走 HTTP/2 的响应会显示 content-type,而一个 HTTP/1.1 的响应则可能显示 Content-Type。无论哪一种情况,这些名称都是大小写不敏感的。
如果你需要发送自定义请求头、指定某个方法,或者带上请求体,请改用 REST API 测试器——它从你自己的浏览器里发起请求,所以能做一些共享服务绝对不能做的事。