如何在 Node.js/Express 后端允许特殊路由使用 CORS?

问题描述 投票:0回答:1

这是我当前的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,
};

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

app.post('/v1/api/webhook', express.raw({ type: 'application/json' }), PaymentController.handleSubscriptionEvent);

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);
});

这是路由器

import express from 'express';
import AdminRouter from './admin.router.js';
import ClientRouter from './client.router.js';
import ServiceRouter from './service.router.js';

const router = express.Router();

router.use('/api/admin', AdminRouter);
router.use('/api', ClientRouter);
router.use('/api/service', ServiceRouter);

export default router;

我想允许 CORS 用于来自 allowedorigins 的几乎所有路线。但关于特殊路线,我想从任何来源访问它们。我的意思是,我希望允许 CORS 用于来自任何起点的特殊路线。特殊路由器是/v1/api/service。

如何在 Node.js/Express 后端执行此操作?

node.js express cors
1个回答
0
投票

对于 ServiceRouter,请使用给定的请求 origin 覆盖 CORS Access-Control-Allow-Origin 。编码的方法之一可能如下。

router.use('/api/service', 
(req,res,next)=> {
res.setHeader('Access-Control-Allow-Origin', req.header('Origin'));
next();
}, 
ServiceRouter);

有关 CORS 主题的更多信息:

众所周知,CORS 检查是由浏览器在收到响应时完成的。 服务器不执行 CORS 检查,而是简单地通过设置 HTTP 响应标头Access-Control-Allow-Origin 来选择加入 CORS。因此,该标头的值可以是anything。仅在浏览器进行 CORS 检查期间才有意义。通过 CORS 检查的有效值为 - '*' 或请求的来源。所有其他值都会导致 CORS 失败。

在这种情况下,除了路由ServiceRouter之外,其他两个路由器将继续与指定的允许来源一起工作。只有路由 ServiceRouter 将始终使用给定的请求源进行响应。因此,此代码将提供所需的功能。

有关更多信息,请参阅文章:如何赢得 CORS

您还可以在这里看到类似的案例:如何在 Express 中禁用单个路由的 CORS,而不重写我的所有路由?

© www.soinside.com 2019 - 2024. All rights reserved.