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

如何在Node.js/Express服务器中为特定路由禁用CORS策略?

解决Express中部分API开放CORS、其余API保留限制的问题

问题说明

使用Node.js/Express开发后端时,需要让特定外部API(如/v1/api/webhook)允许所有来源访问(禁用CORS限制),但其余API仍保留原有的CORS策略(仅允许allowedOrigins内的源访问)。

解决方案思路

Express中间件按注册顺序执行,只需先给需要开放的路由单独配置宽松的CORS规则,再给剩余路由应用原有的严格CORS规则即可,避免全局CORS覆盖特殊路由的配置。

具体修改步骤

  1. 新增宽松CORS配置,允许所有源访问:
const corsOpenOptions = {
  origin: '*',
  methods: 'POST, OPTIONS',
  allowedHeaders: ['Content-Type'],
};
  1. 在全局应用严格CORS之前,给目标路由(如webhook)单独应用宽松CORS:
app.post('/v1/api/webhook', cors(corsOpenOptions), express.raw({ type: 'application/json' }), PaymentController.handleSubscriptionEvent);
  1. 确保其余路由在之后注册,应用原有的严格CORS规则。

修改后的完整server.js代码

import path from 'path';
import cors from 'cors';
import nocache from 'nocache';
import express from 'express';
import mongoose from 'mongoose';
import { fileURLToPath } from 'url';
import bodyParser from 'body-parser';
import Router from './routes/index.js';
import PaymentController from './controllers/client/payment.controller.js';

// Get the directory name of the current module
const __dirname = path.dirname(fileURLToPath(import.meta.url));

mongoose.connect(process.env.DB)
    .then(() => {
        console.log(`Database connected successfully ${process.env.DB}`);
    })
    .catch((error) => console.log(error));

const app = express();

app.use(nocache());

// Combine to frontend for production
if (process.env.MODE == 'production') {
    app.use(express.static(path.join(__dirname, '../production/build')));
} else if (process.env.MODE == 'staging') {
    app.use(express.static(path.join(__dirname, '../staging/build')));
}

const allowedOrigins = [
    'http://localhost:3000'
];

const corsOptions = {
    origin: function (origin, callback) {
        if (!origin) return callback(null, true);
        if (allowedOrigins.indexOf(origin) !== -1) {
            callback(null, true);
        } else {
            callback(new Error('Not allowed by CORS'));
        }
    },
    methods: 'GET, OPTIONS',
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true,
};

// 新增:开放CORS的配置,允许所有源
const corsOpenOptions = {
  origin: '*',
  methods: 'POST, OPTIONS',
  allowedHeaders: ['Content-Type'],
};

// 先给需要开放的路由单独配置CORS,再给其他路由应用严格CORS
app.post('/v1/api/webhook', cors(corsOpenOptions), express.raw({ type: 'application/json' }), PaymentController.handleSubscriptionEvent);

// Apply CORS to most routes
app.use(cors(corsOptions));

app.use(
    bodyParser.json({
        limit: '15360mb',
        type: 'application/json',
    })
);

app.use(
    bodyParser.urlencoded({
        limit: '15360mb',
        extended: true,
        parameterLimit: 5000000,
        type: 'application/json',
    })
);

app.use('/v1/', Router);

// Combile to frontend for production
if (process.env.MODE == 'production') {
    app.get('*', (req, res) => {
        res.sendFile(path.resolve(__dirname, '../production/build', 'index.html'));
    });
} else if (process.env.MODE == 'staging') {
    app.get('*', (req, res) => {
        res.sendFile(path.resolve(__dirname, '../staging/build', 'index.html'));
    });
}

const port = process.env.MODE === 'production' || process.env.MODE === 'staging' ? 3000 : 9200;
const runningMessage = 'Server is running on port ' + port;

app.listen(port, () => {
    console.log(runningMessage);
});

关键说明

  • 中间件顺序是核心:必须先注册开放CORS的路由,再注册全局严格CORS,否则全局CORS会覆盖特殊路由的配置。
  • 针对webhook这类接收第三方请求的接口,配置origin: '*'即可允许所有来源,同时根据实际需求调整methods和allowedHeaders(比如webhook通常只用POST,所以只允许POST和OPTIONS)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:42:36