feat(server): 支持多域名CORS配置

- 实现了逗号分隔的多域名CORS配置解析功能
- 新增parseCorsAllowOrigins函数处理域名列表解析
- 新增getCorsAllowOrigin函数实现动态域名匹配逻辑
- 更新CORS响应头设置逻辑支持多域名验证
- 添加Vary: Origin响应头优化缓存策略
- 修改README文档说明多域名配置方式
This commit is contained in:
LaoShui 2026-03-14 21:03:58 +08:00
parent 7b2507e43d
commit 30e522018f
2 changed files with 48 additions and 3 deletions

View File

@ -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` | 是否启用全局解灰(推荐开启)。开启后所有歌曲都尝试自动解锁。 |

View File

@ -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',