用于在生产环境中调试重定向和 HTTP 标头的小工具集
五个命令行工具和浏览器技巧,帮你看清客户端与服务器之间实际发生了什么
目录
在生产环境中调试 HTTP 的问题
大多数 HTTP 问题在浏览器中是不可见的。重定向链可能悄无声息地失败,缓存标头可能只差一个字符,CORS 策略可能在没有解释的情况下阻止请求。浏览器的开发者工具会展示这次对话的结果,但它们常常隐藏导致问题的原始交互。
这在生产环境中尤其重要,因为你不能随意添加日志或重启服务来查看发生了什么变化。你需要能够展示实际 HTTP 对话的工具:请求标头、响应标头、状态码、重定向目标、耗时。下面是五个可靠完成这项工作的工具,以及与它们互补的浏览器技巧。
curl:基础工具
curl 是首先应该使用的工具,因为它能准确显示服务器发送了什么,中间没有浏览器的解释层。
查看响应标头而不查看响应体:
curl -I https://example.com
跟随重定向并查看每一步:
curl -L -v https://example.com
-v 标志(verbose)会显示完整的请求和响应,包括所有标头。-L 标志会自动跟随重定向。二者结合,可以展示完整的重定向链,而大多数生产问题就出在这里。
只查看重定向位置:
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" -L https://example.com
当你需要验证一条重定向链,又不想被完整标头的噪声干扰时,这很有用。-w 标志会格式化输出,只显示状态码和链中的下一个 URL。
curl 还允许发送自定义标头,这对于测试 CDN 行为、身份验证或 API 端点至关重要:
curl -H "Authorization: Bearer token" -H "Accept: application/json" https://api.example.com
httpie:默认体验更好的 curl
httpie 是一个 Python 工具,功能类似 curl,但语法更容易记住,输出也更容易阅读。它不是替代品——curl 更强大,也安装得更广泛——但对于快速检查来说,httpie 更高效。
查看标头:
http HEAD https://example.com
跟随重定向:
http --follow --all https://example.com
--all 标志会显示重定向链中的每个响应,而不仅仅是最终响应。这相当于 curl -L -v,但输出带有颜色,更容易浏览。
发送 JSON:
http POST https://api.example.com name=value
httpie 默认假定使用 JSON,这在测试 API 时可以减少输入。它还会美化打印响应,使格式错误的标头或意外值更容易被发现。
Browser DevTools:Network 面板
如果问题只在浏览器中发生,浏览器的 Network 面板就是你应该首先查看的地方。它展示的信息与 curl 相同,但也会展示浏览器的解释:是否阻止了请求、如何处理缓存、是否发送了 cookie。
要查看完整的请求和响应标头,请在 Network 面板中点击任意请求,然后查看 Headers 部分。"Raw" 视图会按发送时的原样显示标头,不做格式化。
要查看重定向链,请查找状态码为 3xx 的请求。浏览器会把它们归组到最终请求下,但你可以展开查看每一步。这里通常能发现重定向循环、缺失的 Location 标头,或指向错误域名的重定向。
要查看耗时,请查看任意请求的 Timing 面板。它会显示浏览器在 DNS 查询、TCP 连接、TLS 握手和等待服务器上分别花了多长时间。如果某个重定向很慢,Timing 面板会告诉你问题是网络延迟还是服务器处理。
一个限制是:出于安全原因,浏览器会隐藏某些标头。Set-Cookie 标头可见,但实际 cookie 值会被遮蔽。Authorization 标头有时会被完全隐藏。如果你需要看到这些内容,请使用 curl。
mitmproxy:拦截代理
mitmproxy 是一个 Python 工具,位于浏览器和服务器之间,实时展示每个请求和响应。它比 curl 更复杂,但它是唯一能展示浏览器实际发送内容的工具,包括浏览器自动添加的标头。
启动它:
mitmproxy
然后将浏览器配置为使用 localhost:8080 作为 HTTP 代理。mitmproxy 会在终端界面中展示每个请求。你可以检查标头,在发送前编辑请求,或使用不同参数重放请求。
这对于调试只在浏览器中发生的问题很有用:CORS 预检请求、cookie 处理,或在某些标头存在时失败的请求。它也适合测试你的网站在企业代理或 VPN 后的行为,因为 mitmproxy 可以模拟这些环境。
缺点是设置较复杂。你需要安装根证书,让 mitmproxy 能够拦截 HTTPS 流量,还需要配置浏览器使用代理。快速检查时,curl 更快。深度调试时,mitmproxy 值得投入设置时间。
WebPageTest:生产视角
WebPageTest 是一项免费服务,可以从不同位置的真实浏览器加载你的页面,并展示完整的 HTTP 对话。它比 curl 慢,但能显示真实用户体验到的情况,包括 CDN 行为、DNS 解析和 TLS 协商。
"Request Headers" 和 "Response Headers" 视图会准确显示浏览器发送和接收的内容。"Waterfall" 视图会显示每个请求的耗时,包括重定向。这里通常能发现只在某些地区或某些网络上出现的问题。
WebPageTest 还会显示主文档的重定向链,而大多数重定向问题就发生在这里。如果你的网站先从 http:// 重定向到 https://,再从 www. 重定向到非 www.,然后从 / 重定向到 /en/,WebPageTest 会显示全部三个步骤以及每一步花费的时间。
对于帮助你验证和优化这些 HTTP 基础项的工具,Wux Webtools offers several utilities 可完全在浏览器中运行,包括标头分析器和重定向检查器,并通过在客户端侧处理所有内容来尊重你的隐私。
当标头“说谎”时
最难处理的 HTTP 问题,是服务器发送相互矛盾的标头。Cache-Control 标头说 no-cache,但 Expires 标头却说资源一年内有效。Location 标头指向相对 URL,但 Content-Location 标头指向另一个位置。浏览器必须猜测该相信哪一个,而不同浏览器的猜测并不相同。
发生这种情况时,你需要按服务器发送的顺序查看原始标头。curl -v 可以做到。mitmproxy 也可以。浏览器的 DevTools 有时会为了可读性重新排序标头,从而掩盖问题。
另一个常见问题是:标头不是由你的应用添加的,而是由 CDN 或负载均衡器添加的。如果你在调试缓存问题,就需要知道 Cache-Control 标头来自你的应用,还是来自 CDN。curl 会显示最终结果,但不会告诉你每个标头来自哪里。为此,你需要绕过 CDN(直接访问源站服务器)并比较标头。
重定向循环问题
重定向循环是生产环境中最常见的 HTTP 问题。当两台服务器对某个 URL 应该指向哪里意见不一致时,就会发生这种情况:CDN 重定向到源站,源站又重定向回 CDN。或者负载均衡器将 HTTP 重定向到 HTTPS,但应用因为看不到 X-Forwarded-Proto 标头,又把 HTTPS 重定向回 HTTP。
要调试这个问题,你需要看到完整的重定向链,包括每一步的 Location 标头。curl -L -v 可以做到,但它会在 50 次重定向后停止,以防止无限循环。如果你触达了这个限制,就说明存在重定向循环。
修复通常是配置变更:告诉应用信任 X-Forwarded-Proto 标头,或告诉 CDN 停止重定向已经是 HTTPS 的请求。但在看到循环之前,你无法修复它,而浏览器在放弃之前通常只会显示少数几次重定向。
先检查什么
当生产环境中出现故障时,按以下顺序检查:
- 状态码:它是否符合预期?301 是永久重定向,302 是临时重定向,307 会保留 HTTP 方法。如果你看到的状态码不对,问题就在重定向配置中。
- Location 标头:它是否指向正确的位置?它是绝对 URL 还是相对 URL?相对 URL 会根据当前 URL 解析,如果基础 URL 不是你以为的那样,就可能产生意外结果。
- 缓存标头:浏览器是否在缓存重定向?301 重定向默认会被缓存,这意味着配置错误的重定向即使在修复后,也可能让你的网站继续故障数小时。检查
Cache-Control和Expires标头,了解浏览器会记住这个重定向多久。
- CORS 标头:如果请求是跨源的,服务器是否发送了正确的
Access-Control-Allow-Origin标头?如果没有,浏览器会阻止请求,你会在控制台看到 CORS 错误。服务器的响应标头是唯一能修复这个问题的地方——你无法在浏览器中绕过它。
- 耗时:请求花了多长时间?如果很慢,是网络延迟还是服务器处理?浏览器的 DevTools 和 WebPageTest 都会显示耗时拆分,告诉你时间花在了哪里。
要更深入了解浏览器在隐私和标头方面的行为变化,请参阅 what changed for cookies in 2026 and what to do about it,其中介绍了近期浏览器更新对标头和同意机制的影响。
关键要点
curl -L -v会展示完整的重定向链和所有标头,不经过浏览器解释- 浏览器的 Network 面板会显示浏览器对响应做了什么,包括缓存和 CORS 决策
mitmproxy会显示浏览器发送了什么,包括浏览器自动添加的标头- WebPageTest 会显示真实用户体验到的情况,包括 CDN 行为和地区差异
- 重定向循环和相互矛盾的标头是最常见的生产问题,如果不检查原始 HTTP,它们就是不可见的
FAQ
Q: 为什么 curl 显示的标头和浏览器不同?
A: 因为浏览器会自动添加标头(User-Agent、Accept、Cookie),并按照自己的规则处理缓存和 CORS。curl 只发送你告诉它发送的内容。要查看浏览器实际发送的内容,请使用 mitmproxy 或浏览器的 DevTools。
Q: 如何调试只发生在部分用户身上的重定向?
A: 检查重定向是否依赖用户发送的标头:User-Agent、Accept-Language、Cookie,或 IP 地址(通过 X-Forwarded-For)。使用 curl 发送与该用户相同的标头,或使用 WebPageTest 从该用户所在位置加载页面。
Q: 301 和 302 重定向有什么区别?
A: 301 是永久重定向,会告诉浏览器缓存该重定向(有时是永久缓存)。302 是临时重定向,会告诉浏览器不要缓存它。如果你不确定该用哪一个,请使用 302——之后随时可以改成 301。
Q: 为什么我的重定向在 curl 中有效,但在浏览器中无效?
A: 很可能是因为浏览器缓存了旧的重定向,或者浏览器因为 CORS 或混合内容规则阻止了重定向。检查浏览器 DevTools 控制台中的错误,并检查 Cache-Control 标头,确认浏览器是否正在使用缓存响应。
Q: 如何查看 CDN 添加的标头?
A: 使用 curl 访问 CDN URL,然后再次使用 curl 直接访问源站服务器(绕过 CDN)。比较标头。只出现在第一个响应中的标头就是来自 CDN 的标头。
<!-- tool-cta:start -->
💡 试试这个: 在排查重定向问题时,Redirect Checker 会跟踪完整链路,并显示每一跳的状态码和标头。
<!-- tool-cta:end -->
Sources
- curl documentation — curl 命令行选项和行为的官方参考
- HTTPie documentation — httpie 语法和功能指南
- MDN Web Docs: HTTP redirections — 对 HTTP 重定向状态码和行为的全面解释
- WebPageTest documentation — 如何解读 WebPageTest 结果和标头


