4.6 KiB
技能加点图片导出的跨域配置
技能树使用 https://image.dnftools.com 上的图标。普通 <img> 展示不要求 CORS,但 html-to-image 导出时需要 fetch 图标并内嵌到图片,因此图床必须返回允许跨域读取的响应头。前端不需要改动,no-cors 无法读取图片内容。
允许范围
仅允许 HTTP / HTTPS 的 *.dnftools.com 来源,包括多级子域和带端口的来源。例如 https://dcalc.dnftools.com、https://test.dcalc.dnftools.com 和 http://dev.dnftools.com:5173。
不包括裸域 https://dnftools.com、localhost、null、其他域名或 https://dnftools.com.example.org 这样的伪装后缀。CORS 响应头不能写成 *.dnftools.com,应校验 Origin 后返回该完整 Origin,并设置 Vary: Origin 让缓存区分来源。
Nginx / OpenResty 图床
下面的配置适用于直接编辑站点 server { ... } 的环境,不需要在外层 http 中声明 map。
1. 在 server 层增加来源校验和默认响应头
放在 server_name image.dnftools.com; 后面,保留其余配置和原有的 HSTS 头:
set $image_cors_origin "";
if ($http_origin ~* "^https?://([a-z0-9-]+\.)+dnftools\.com(:[0-9]+)?$") {
set $image_cors_origin $http_origin;
}
add_header Access-Control-Allow-Origin $image_cors_origin always;
add_header Vary "Origin" always;
未匹配的来源对应空值,Nginx 不输出 Access-Control-Allow-Origin。现有 location / 没有自己的 add_header,会继承这里的响应头。
2. 替换静态资源 location
这个 location 已有自己的 add_header,所以必须在这里也设置 CORS 和 Vary,不能只依赖 server 层。保留原来的文件路径、缓存、HSTS 和字符集:
location ~* \.(?:jpg|jpeg|png|gif|webp|avif|svg|ico|bmp|swf|css|js|woff|woff2|ttf|eot)$ {
root /dcalc/image;
expires 7d;
add_header Cache-Control "public, max-age=604800";
add_header Strict-Transport-Security "max-age=31536000";
add_header Access-Control-Allow-Origin $image_cors_origin always;
add_header Vary "Origin" always;
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always;
add_header Access-Control-Allow-Headers "If-None-Match, If-Modified-Since" always;
add_header Access-Control-Max-Age "86400" always;
if ($request_method = OPTIONS) {
return 204;
}
try_files $uri =404;
charset utf-8,gbk;
}
always 使 CORS 头也适用于 304 和错误响应;原配置的 error_page 404 /404.html 内部跳转会由 location / 继承 server 层的 CORS 和 Vary 头。其余 location、证书和 HTTP 跳转配置保持不变。不要再保留之前的 Access-Control-Allow-Origin "*",也不要重复添加此头。
这是对浏览器跨域脚本读取的限制,不是防盗链或访问鉴权;其他来源仍可能展示普通 img,或直接下载公开图片。当前导出无需 Cookie,不需要 Access-Control-Allow-Credentials。
3. 检查、重载及验证
在实际运行 Nginx / OpenResty 的环境中执行(容器部署则在对应容器内执行):
nginx -t
nginx -s reload
# 应返回 Access-Control-Allow-Origin: https://dcalc.dnftools.com
# 并包含 Vary: Origin
curl -I -H 'Origin: https://dcalc.dnftools.com' \
'https://image.dnftools.com/characters/gunner_female/spitfire_female/profile.png'
# 不应返回 Access-Control-Allow-Origin
curl -I -H 'Origin: https://dnftools.com.example.org' \
'https://image.dnftools.com/characters/gunner_female/spitfire_female/profile.png'
如果前面还有 CDN,需让其遵守 Vary / 按 Origin 区分缓存,或在边缘执行相同的来源校验,并刷新旧响应头缓存。最后回到技能设置页导出,检查 PNG 中包含图标、等级和觉醒绑定。
仓库自带的 Node 图片服务
pnpm run dev:image 使用 scripts/image.js,已采用同样的来源规则:匹配时返回请求 Origin,其他来源不返回 Access-Control-Allow-Origin;所有响应设置 Vary: Origin,保留 HEAD、304、错误响应和 OPTIONS 支持。
本地前端通过 Vite 的 /image 同源代理访问图片,不需要放行 localhost。部署使用 Node 服务时需要重启该进程;当前生产配置直接通过 Nginx 读取 /dcalc/image,所以生产生效点是上面的 Nginx 修改,无需重新构建前端。