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 ba4466c..ff58fc1 100644 --- a/server.js +++ b/server.js @@ -127,15 +127,45 @@ 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 + } + + return null +} + /** * Construct the server of NCM API. * * @param {ModuleDefinition[]} [moduleDefs] Customized module definitions [advanced] * @returns {Promise} The server instance. */ -async function consturctServer(moduleDefs) { +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 +177,17 @@ async function consturctServer(moduleDefs) { */ app.use((req, res, next) => { if (req.path !== '/' && !req.path.includes('.')) { + const corsAllowOrigin = getCorsAllowOrigin( + allowOrigins, + req.headers.origin, + ) + const shouldSetVaryHeader = corsAllowOrigin && 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', @@ -359,7 +396,7 @@ async function serveNcmApi(options) { ) } }) - const constructServerSubmission = consturctServer(options.moduleDefs) + const constructServerSubmission = constructServer(options.moduleDefs) const [_, app] = await Promise.all([ checkVersionSubmission,