这是我当前的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 后端执行此操作?
对于 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,而不重写我的所有路由?