别再被骗了:深度解析“Provisional headers are shown”与 OPTIONS 预检请求

0 阅读3分钟

在前端开发调试中,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

  1. 方法限制: 只能是 GETPOSTHEAD
  2. Header 限制: 只能是标准的几个头(Accept, Content-Type 等)。
  3. Content-Type 限制: 仅限于 text/plainmultipart/form-dataapplication/x-www-form-urlencoded

重点坑位: 现在的项目几乎都是 application/json 交互,或者带自定义的 Authorization 令牌,这百分之百会触发 OPTIONS


三、 当“临时报头”遇上 OPTIONS:最隐蔽的坑

这是今晚最关键的知识点:为什么 OPTIONS 成功了,正式请求还是显示“临时报头”?

场景还原:

  1. 浏览器发送 OPTIONS,后端返回 200 OK
  2. 紧接着的正式请求状态为 (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 的预检逻辑,你就能从容判断它是死在了前端的并发或安全限制,还是死在了后端的权限配置。