From 7b2507e43d6208077084f86fe93d0e35e68004de Mon Sep 17 00:00:00 2001 From: LaoShui <79132480+laoshuikaixue@users.noreply.github.com> Date: Sat, 14 Mar 2026 19:24:52 +0800 Subject: [PATCH 1/3] =?UTF-8?q?refactor(server):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=90=8D=E6=8B=BC=E5=86=99=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 consturctServer 函数名更正为 constructServer - 更新调用处的函数名称以保持一致性 --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index ba4466c..04f5bfd 100644 --- a/server.js +++ b/server.js @@ -133,7 +133,7 @@ async function checkVersion() { * @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 app.set('trust proxy', true) @@ -359,7 +359,7 @@ async function serveNcmApi(options) { ) } }) - const constructServerSubmission = consturctServer(options.moduleDefs) + const constructServerSubmission = constructServer(options.moduleDefs) const [_, app] = await Promise.all([ checkVersionSubmission, From 30e522018f72987ee318adf2664ddeca003777bf Mon Sep 17 00:00:00 2001 From: LaoShui <79132480+laoshuikaixue@users.noreply.github.com> Date: Sat, 14 Mar 2026 21:03:58 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(server):=20=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?=E5=9F=9F=E5=90=8DCORS=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了逗号分隔的多域名CORS配置解析功能 - 新增parseCorsAllowOrigins函数处理域名列表解析 - 新增getCorsAllowOrigin函数实现动态域名匹配逻辑 - 更新CORS响应头设置逻辑支持多域名验证 - 添加Vary: Origin响应头优化缓存策略 - 修改README文档说明多域名配置方式 --- README.MD | 2 +- server.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) 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', From 27aa9a01cb0d6792035af33efd63927d24c0bc82 Mon Sep 17 00:00:00 2001 From: LaoShui <79132480+laoshuikaixue@users.noreply.github.com> Date: Sat, 14 Mar 2026 21:14:18 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(cors):=20=E4=BF=AE=E5=A4=8DCORS?= =?UTF-8?q?=E6=BA=90=E9=AA=8C=E8=AF=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除无效的请求源回退逻辑 - 简化Vary头设置条件判断 - 优化CORS允许源验证流程 --- server.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/server.js b/server.js index 189f328..ff58fc1 100644 --- a/server.js +++ b/server.js @@ -153,10 +153,6 @@ function getCorsAllowOrigin(allowOrigins, requestOrigin) { return requestOrigin } - if (!requestOrigin) { - return allowOrigins[0] || null - } - return null } @@ -185,11 +181,7 @@ async function constructServer(moduleDefs) { allowOrigins, req.headers.origin, ) - const shouldSetVaryHeader = - allowOrigins && - !allowOrigins.includes('*') && - req.headers.origin && - corsAllowOrigin + const shouldSetVaryHeader = corsAllowOrigin && corsAllowOrigin !== '*' res.set({ 'Access-Control-Allow-Credentials': true, ...(corsAllowOrigin