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

已配置CORS仍报错:Node.js/Express API跨域请求失败排查

Express + Vercel 部署后CORS预检错误的排查与解决

问题重现

前端部署在 https://www.linkgrid.site,调用部署在Vercel的Express API(https://linkgrid-api.vercel.app/api/users/create)时,出现CORS预检错误:

Access to XMLHttpRequest at 'https://linkgrid-api.vercel.app/api/users/create' from origin 'https://www.linkgrid.site' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

已完成配置:

  • Express中启用cors中间件,允许包含https://www.linkgrid.site在内的多个源
  • vercel.json中添加了CORS相关响应头
  • 前后端均确认部署正确

核心原因分析

当前配置存在两处关键问题:

1. Vercel配置的Origin与请求源不匹配

你的vercel.json中Access-Control-Allow-Origin仅设置为https://linkgrid.site,但实际发起请求的源是https://www.linkgrid.site——带www和不带www属于不同域名,导致Vercel返回的CORS头与请求源不匹配,直接触发预检失败。

2. 双重CORS配置的冲突

同时在Vercel路由层和Express应用层配置CORS,可能导致响应头重复或优先级冲突。比如Vercel先返回了不匹配的Origin头,浏览器直接判定预检失败,不会等待Express返回正确的头。

解决方案

方案一:移除Vercel的CORS配置,让Express完全处理

推荐优先让应用层(Express)处理CORS,避免平台层和应用层的配置冲突:

  1. 修改vercel.json,删除routes.headers中的所有CORS相关配置,保留核心路由和构建配置:
{
  "version": 2,
  "builds": [
    {
      "src": "dist/server.js",
      "use": "@vercel/node",
      "config": { "includeFiles": ["dist/**"] }
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "dist/server.js"
    }
  ]
}
  1. 确认Express的cors中间件配置正确,已包含https://www.linkgrid.site(你的app.ts中已配置,无需修改),同时确保编译后的dist/server.js正确包含这段逻辑(可本地编译后检查js文件内容)。

  2. 重新部署Vercel后端,确保新配置生效。

方案二:修正Vercel的Origin配置(保留双重配置场景)

如果需要在Vercel层配置CORS,需确保Origin匹配所有允许的源:

  1. 修改vercel.json中的Access-Control-Allow-Origin为动态值$origin(Vercel支持的变量,自动匹配请求的Origin),同时保留其他CORS头:
{
  "version": 2,
  "builds": [
    {
      "src": "dist/server.js",
      "use": "@vercel/node",
      "config": { "includeFiles": ["dist/**"] }
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "dist/server.js",
      "headers": {
        "Access-Control-Allow-Origin": "$origin",
        "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,OPTIONS,PATCH",
        "Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization",
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Max-Age": "86400"
      }
    }
  ]
}

注意:使用$origin时,需确保业务逻辑信任所有请求源,或结合Vercel边缘函数做进一步验证。

额外排查步骤

  1. 测试预检请求:用curl手动发送OPTIONS请求,查看实际响应头:
curl -X OPTIONS https://linkgrid-api.vercel.app/api/users/create -H "Origin: https://www.linkgrid.site" -v

重点检查响应中是否存在Access-Control-Allow-Origin,且值为https://www.linkgrid.site。

  1. 清除Vercel缓存:在Vercel控制台的项目部署页面,点击"Redeploy"并选择"Clear build cache",确保新配置不被缓存影响。

  2. 检查Express中间件顺序:确保cors中间件是第一个被加载的(你的代码中已做到),避免其他中间件(如helmet、limiter)提前拦截请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:12:04