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

Express配置CORS后fetch发POST跨域请求返回400错误排查

Express CORS配置失效+POST请求400报错解决方案

问题根因

报错由三个独立的配置错误共同导致,对中间件顺序的判断只对了一半:

  • 客户端请求未做序列化:fetch的body字段直接传入原生JS对象时,浏览器不会自动转成JSON格式,服务端bodyParser.json()收到非标准JSON格式的请求体时,会直接返回400 Bad Request
  • cors包配置参数完全错误:npm官方cors中间件不识别Access-Control-Allow-Origin、Allow-Methods这类HTTP响应头名作为配置键,合法配置键为origin、methods、allowedHeaders,原有配置完全没有生效
  • 预检请求未放行:带Content-Type: application/json的POST请求属于非简单请求,浏览器会先发送OPTIONS方法的预检请求,原有配置的允许方法列表里既没有OPTIONS,还写了不存在的FETCH方法,导致预检直接被拦截

修复方案

客户端代码修正

给请求体增加JSON序列化逻辑,修正后代码:

async modifyTrip() {
  const submitData = {
    data: "test",
    mezzo: "test",
    coordinate: ["test"],
    tappe: ["test"],
  };
  const modifyform = document.getElementById("add-form");
  modifyform.onsubmit = async (e) => {
    e.preventDefault();
    await fetch("http://localhost:3000/trips", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      // 必须序列化JS对象为JSON字符串
      body: JSON.stringify(submitData),
    });
  };
}

服务端配置修正

CORS中间件必须放在所有业务中间件、路由之前挂载,同时修正cors包的配置参数,修正后代码:

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();

// 最先挂载CORS中间件,使用cors包标准配置
app.use(
  cors({
    origin: "*",
    methods: ["GET", "POST", "DELETE", "OPTIONS"],
    allowedHeaders: ["Content-Type", "Accept"]
  })
);

// 再挂载body解析中间件
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 最后挂载业务路由
app.use("/user", userRoutes);
app.use("/trips", tripsRoutes);

app.listen(3000);

验证说明:修复后打开浏览器开发者工具网络面板,先确认OPTIONS预检请求返回204状态码,后续POST请求即可正常处理,不会再出现跨域拦截或400报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:24:15