在前端开发调试中,Chrome 开发者工具里的 “Provisional headers are shown” (显示的是临时报头)常年霸占“最让人困惑报错”榜单。本文将带你拆解这个现象背后的底层逻辑,以及它与 OPTIONS 请求之间剪不断理还乱的关系。
一、 “临时报头”:请求真的发出了吗?
当你在 Network 面板看到这句话时,浏览器其实在告诉你: “我还没拿到真正的响应头,所以先给你看我‘打算’发的这些。”
1. 确实没发出去(死在自家门口)
- 插件拦截: 比如 AdBlock 杀掉了广告请求。
- 缓存命中: 命中了强缓存(Disk Cache / Memory Cache),浏览器直接本地取货,压根没过网卡。
- 并发限制: 同域名超过 6 个连接,该请求在排队等待。
- HSTS 强制跳转: 浏览器内部将 HTTP 重定向到 HTTPS。
2. 发出了但没结果(死在路上或对岸)
- 服务器装死: TCP 连接成功了,请求也发出去了,但后端逻辑死循环或宕机,没给任何回话。
- 网络断裂: 典型的 Silent Drop,连接中途断开,浏览器还在傻等。
二、 OPTIONS 请求:浏览器的“安全探针”
很多时候,“临时报头”出现在一个正式请求(如 POST)上,是因为它前面的 OPTIONS 请求出了问题。
1. 为什么会有 OPTIONS?
这是浏览器的 CORS(跨源资源共享) 预检机制。为了保证安全,浏览器在执行“危险”操作前,会先发一个 OPTIONS 询问服务器:“我可以这样做吗?”
2. 触发 OPTIONS 的三大条件
只要不满足以下任何一个条件,就会触发 OPTIONS:
- 方法限制: 只能是
GET、POST、HEAD。 - Header 限制: 只能是标准的几个头(
Accept,Content-Type等)。 - Content-Type 限制: 仅限于
text/plain、multipart/form-data、application/x-www-form-urlencoded。
重点坑位: 现在的项目几乎都是
application/json交互,或者带自定义的Authorization令牌,这百分之百会触发OPTIONS。
三、 当“临时报头”遇上 OPTIONS:最隐蔽的坑
这是今晚最关键的知识点:为什么 OPTIONS 成功了,正式请求还是显示“临时报头”?
场景还原:
- 浏览器发送
OPTIONS,后端返回200 OK。 - 紧接着的正式请求状态为
(canceled)或(pending),显示Provisional headers are shown。
背后真相:
这通常是 “准考证不合格” 导致的。虽然 OPTIONS 请求本身通了,但它返回的 Header(如 Access-Control-Allow-Headers)里没有涵盖正式请求将要带的字段。
结果: 浏览器认为“握手失败”,出于安全考虑,直接在内部把正式请求给拦截了,请求根本没出网卡。
四、 避坑与优化指南
1. 别只盯着 Network,看实际抓包
当看到“临时报头”时,不要局限在浏览器控制台,浏览器控制台Network中体现出的请求不一定是实际发起的。如果是 CORS 导致的拦截,whistle中会抓不到。
- 抓包工具里有:请求已发出。
- 抓包工具里没有:请求死在浏览器内部。
2. 性能优化:减少 OPTIONS
每个 OPTIONS 都是一次额外的往返(RTT)。在生产环境,建议后端配置:
Access-Control-Max-Age: 86400
这会让浏览器在 24 小时内记住该路径的权限,无需每次都预检。
结语
“Provisional headers are shown” 不是一种报错,而是一种 “等待中” 的状态。理解了 CORS 的预检逻辑,你就能从容判断它是死在了前端的并发或安全限制,还是死在了后端的权限配置。