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

Vercel部署后Swagger UI调用Express API遇CORS请求失败问题

问题描述

我用Express.js开发了一套API,配置了Swagger文档和CORS规则。这套API在Heroku上部署后运行正常,但部署到Vercel后,通过Swagger UI调用接口时一直出现以下错误:

Failed to fetch.
Possible Reasons:

CORS
Network Failure
URL scheme must be "http" or "https" for CORS request.

我已经添加了vercel.json文件配置CORS响应头,但问题依然存在。相关代码配置如下:

Express中的Swagger及CORS配置

// Swagger definition
const swaggerDefinition = {
  swagger: "2.0",
  info: {
    version: "1.0.0",
    title: "API",
    description: "API Documentation for fetching data"
  },
  host: "localhost:3000",
  schemes: ["http"]
};

// Options for the swagger docs
const options = {
  swaggerDefinition,
  apis: ["./api/index.js"], // Update with actual path to the API file
};

// Initialize swagger-jsdoc
const swaggerSpec = swaggerJsdoc(options);

const CSS_URL = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.1.0/swagger-ui.min.css"


// Then pass these options to cors:
app.use(cors(options));

// Serve swagger docs
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, {
  customCss:
      '.swagger-ui .opblock .opblock-summary-path-description-wrapper { align-items: center; display: flex; flex-wrap: wrap; gap: 0 10px; padding: 0 10px; width: 100%; }',
  customCssUrl: CSS_URL,
}));

vercel.json配置

{
  "version": 2,
  "builds": [
    { "src": "api/*.js", "use": "@vercel/node" }
  ],
  "routes": [
    { "src": "/(.*)", "dest": "/api/index.js" }
  ],
  "headers": [
    {
      "source": "/api/index.js",
      "headers": [
        { "key": "Access-Control-Allow-Credentials", "value": "true" },
        { "key": "Access-Control-Allow-Origin", "value": "*" },
        { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
        { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
      ]
    }
  ]
}

解决方案

1. 修正Swagger配置的Host和Scheme

你的Swagger定义里硬编码了本地地址localhost:3000和http协议,但Vercel部署后是HTTPS的线上域名,这会导致Swagger UI用本地地址调用线上API,直接触发CORS和URL协议错误。

修改Swagger定义,动态适配生产环境:

const swaggerDefinition = {
  swagger: "2.0",
  info: {
    version: "1.0.0",
    title: "API",
    description: "API Documentation for fetching data"
  },
  host: process.env.NODE_ENV === 'production' ? process.env.VERCEL_URL : "localhost:3000",
  schemes: process.env.NODE_ENV === 'production' ? ["https"] : ["http"]
};

Vercel会自动注入VERCEL_URL环境变量,直接使用即可。

2. 修复CORS中间件的配置错误

你把Swagger的配置对象传给了cors()中间件,这完全错误——cors()需要的是CORS规则配置,不是Swagger的选项。

把这行代码:

app.use(cors(options));

替换为:

// 自定义符合需求的CORS规则
app.use(cors({
  origin: '*',
  credentials: true,
  methods: ['GET', 'OPTIONS', 'PATCH', 'DELETE', 'POST', 'PUT'],
  allowedHeaders: ['X-CSRF-Token', 'X-Requested-With', 'Accept', 'Accept-Version', 'Content-Length', 'Content-MD5', 'Content-Type', 'Date', 'X-Api-Version']
}));

这样CORS规则才能正确生效。

3. 调整vercel.json的Headers匹配范围

当前source: "/api/index.js"仅匹配单个文件的请求,但Swagger UI调用的是API接口路径(比如/api/users),需要扩大匹配范围:

"headers": [
  {
    "source": "/(.*)",
    "headers": [
      { "key": "Access-Control-Allow-Credentials", "value": "true" },
      { "key": "Access-Control-Allow-Origin", "value": "*" },
      { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
      { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
    ]
  }
]

这样所有请求都会带上正确的CORS响应头。

4. 确认Vercel环境变量设置

在Vercel项目的「环境变量」设置中,添加NODE_ENV并设为production,确保Swagger的动态配置生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:52:28