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

浏览器与服务器端均遭遇CORS验证失败问题求助

CORS问题排查与解决方案

问题场景

客户端页面部署在localhost:3000,通过fetch向localhost:3001发送POST请求时,浏览器触发了预检OPTIONS请求,最终返回CORS报错。

客户端代码(index.html)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    async function post() {
      const res = await fetch('http://localhost:3001', {
        method: 'POST',
        body: '{"msg":1}',
        headers: {
          'Access-Control-Allow-Origin': 'http://localhost:3000',
          'Content-Type': 'text/plain'
        },
        mode: 'cors'
      })
      console.log(await res.text())
    }
  </script>
</head>

<body>
  <button onclick="post()">POST</button>
</body>

</html>

服务端代码(server.js,基于Express)

// server.js using express
import express from 'express'
const server = express()
server.options('*', (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000') // 小写设置同样无效
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
    res.setHeader('Access-Control-Allow-Credentials', 'true')
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
    res.send();
})
server.post('/', (req, res) => {
    console.log('POST /')
    res.send('OK')
})
server.listen(3001, () => {
    console.log('listening')
})

报错信息

Access to fetch at 'http://localhost:3001/' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.

Wireshark捕获的请求信息

Wireshark捕获的HTTP请求信息

问题原因

  1. 非法请求头设置:Access-Control-Allow-Origin是服务端返回给客户端的响应头,不属于客户端请求时该携带的头。客户端额外添加这个头后,服务端预检响应的Access-Control-Allow-Headers未包含该字段,触发报错。
  2. 原本Content-Type: text/plain属于简单请求范畴,但因添加了非法请求头,浏览器自动触发预检OPTIONS请求。

解决方案

1. 修正客户端请求头

移除fetch配置中多余的Access-Control-Allow-Origin头,修改后客户端脚本如下:

<script>
  async function post() {
    const res = await fetch('http://localhost:3001', {
      method: 'POST',
      body: '{"msg":1}',
      headers: {
        'Content-Type': 'text/plain'
      },
      mode: 'cors'
    })
    console.log(await res.text())
  }
</script>

2. 优化服务端配置

当前场景下原有服务端配置已满足需求,若后续需添加自定义请求头,需确保Access-Control-Allow-Headers包含对应字段。建议在POST接口中也返回Access-Control-Allow-Origin头,避免潜在问题:

server.post('/', (req, res) => {
    console.log('POST /')
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000')
    res.send('OK')
})

内容的提问来源于stack exchange,提问作者Jackoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:05:28