You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSFiddle中POST请求首次预检失败及预检顺序相关疑问

CORS预检请求相关问题解答

测试代码

前端Fetch代码

const data = { name: 'example', password: 'password'};

fetch('http://localhost:3001', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data),
})
  .then((response) => response.json())
  .then((data) => {
    console.log('Success:', data);
  })
  .catch((error) => {
    console.error('Error:', error);
  });

后端Express代码

const express = require('express')

const app = express()

app.get('/', (req, res) => {
  res.send('Hi')
})

app.post('/', (req, res) => {
  console.log('received')
  res.send('Received')
})

app.listen(3001, () => {
  console.log('Listening on port', 3001)
})

问题解答

1. POST请求的首次预检(preflight)请求失败是否属于正常情况?

不正常。预检请求失败的核心原因是你的Express后端没有处理OPTIONS请求,也未返回任何CORS相关响应头,导致浏览器的同源策略校验不通过。对于包含Content-Type: application/json的POST请求,浏览器会判定为非简单请求,必须先发起OPTIONS预检请求,确认服务器允许跨域后才会发送实际POST请求。服务器没有配置CORS支持时,预检请求会直接失败。

2. 成功的预检请求不应在POST请求之前发起吗?服务器端POST处理代码未执行(无日志输出),说明浏览器取消了POST请求,浏览器如何在预检请求完成前就决定不发送POST请求?

正常逻辑下,预检请求(OPTIONS)必然在实际请求(POST)之前发起,你看到的“fetch请求之后发生预检”是浏览器DevTools的显示顺序误导,实际网络请求的优先级是预检先发送。服务器没收到POST请求,是因为预检请求失败后,浏览器直接拦截了后续的实际请求,根本不会将POST请求发送到服务器,自然不会触发后端的POST处理逻辑。

补充场景分析

  • 改用本地HTML页面测试后预检不再失败:如果本地HTML页面和后端服务同属localhost域名,属于同源请求,浏览器不会触发预检流程。此时你看到的OPTIONS请求可能是其他操作触发,或是DevTools的显示偏差。
  • GET请求控制台报错但网络面板无报错:GET请求属于简单请求,浏览器不会发起预检,会直接发送请求。但如果服务器未返回CORS允许的响应头,浏览器会拦截响应内容,在控制台抛出跨域错误;但网络层面请求已经完成,所以网络面板不会显示请求失败。

内容的提问来源于stack exchange,提问作者Dropin' Science

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:20:12