diff --git a/README.MD b/README.MD index 9d2137b..a3c6cbb 100644 --- a/README.MD +++ b/README.MD @@ -130,7 +130,7 @@ $ sudo docker run -d -p 3000:3000 ncm-api | 变量名 | 默认值 | 说明 | |----------------------------|--------------------------------------|----------------------------------------------------| -| **CORS_ALLOW_ORIGIN** | `*` | 允许跨域请求的域名。若需要限制,请指定具体域名(例如 `https://example.com`)。 | +| **CORS_ALLOW_ORIGIN** | `*` | 允许跨域请求的域名。可填写单个源,或使用逗号分隔多个源(例如 `https://a.com,https://b.com`)。 | | **ENABLE_PROXY** | `false` | 是否启用反向代理功能。 | | **PROXY_URL** | `https://your-proxy-url.com/?proxy=` | 代理服务地址。仅当 `ENABLE_PROXY=true` 时生效。 | | **ENABLE_GENERAL_UNBLOCK** | `true` | 是否启用全局解灰(推荐开启)。开启后所有歌曲都尝试自动解锁。 | diff --git a/server.js b/server.js index 04f5bfd..189f328 100644 --- a/server.js +++ b/server.js @@ -127,6 +127,39 @@ async function checkVersion() { }) } +function parseCorsAllowOrigins(corsAllowOrigin) { + if (!corsAllowOrigin) { + return null + } + + const origins = corsAllowOrigin + .split(',') + .map((origin) => origin.trim()) + .filter(Boolean) + + return origins.length > 0 ? origins : null +} + +function getCorsAllowOrigin(allowOrigins, requestOrigin) { + if (!allowOrigins) { + return requestOrigin || '*' + } + + if (allowOrigins.includes('*')) { + return '*' + } + + if (requestOrigin && allowOrigins.includes(requestOrigin)) { + return requestOrigin + } + + if (!requestOrigin) { + return allowOrigins[0] || null + } + + return null +} + /** * Construct the server of NCM API. * @@ -136,6 +169,7 @@ async function checkVersion() { async function constructServer(moduleDefs) { const app = express() const { CORS_ALLOW_ORIGIN } = process.env + const allowOrigins = parseCorsAllowOrigins(CORS_ALLOW_ORIGIN) app.set('trust proxy', true) /** @@ -147,10 +181,21 @@ async function constructServer(moduleDefs) { */ app.use((req, res, next) => { if (req.path !== '/' && !req.path.includes('.')) { + const corsAllowOrigin = getCorsAllowOrigin( + allowOrigins, + req.headers.origin, + ) + const shouldSetVaryHeader = + allowOrigins && + !allowOrigins.includes('*') && + req.headers.origin && + corsAllowOrigin res.set({ 'Access-Control-Allow-Credentials': true, - 'Access-Control-Allow-Origin': - CORS_ALLOW_ORIGIN || req.headers.origin || '*', + ...(corsAllowOrigin + ? { 'Access-Control-Allow-Origin': corsAllowOrigin } + : {}), + ...(shouldSetVaryHeader ? { Vary: 'Origin' } : {}), 'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type', 'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS', 'Content-Type': 'application/json; charset=utf-8',