解决跨域问题解决
1)后台去增加处理,解决跨域问题。
2)nginx布署的时候处理,解决跨域问题。
下面以域名www.xxx.com为宿主域名,当然也可以是二级域名:app.xxx.com等等。
配制如下:
add_header 'Access-Control-Allow-Origin' 'https://www.xxx.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
表明:指定的域名可以上传。
然后会报一个:
chunk-vendors.3e57df28.js:13 Refused to get unsafe header "content-disposition"
add_header 'Access-Control-Expose-Headers' 'Content-Disposition' always;
这样就可以处理好了。
跨域解决可能方案
这份配置 能解决大部分跨域场景,但存在一个关键细节问题,修复后可覆盖绝大多数实际需求。以下是详细分析:
一、当前配置的跨域支持(已生效部分)
你配置的跨域响应头,已经覆盖了核心场景:
nginx
add_header 'Access-Control-Allow-Origin' '*' always; # 允许所有域名跨域(简单场景够用)
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always; # 允许常用请求方法
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always; # 允许常用自定义头
add_header 'Access-Control-Allow-Credentials' 'true' always; # 允许携带 Cookie/凭证
已支持的场景:
- 简单跨域请求(GET/POST,无自定义头、Cookie);
- 带自定义头(如
Authorization、Content-Type: application/json)的预检请求(OPTIONS); - 携带 Cookie / 凭证的跨域请求。
二、关键问题:Access-Control-Allow-Origin: * 与凭证冲突
问题描述:
当你设置 Access-Control-Allow-Credentials: true(允许携带凭证)时,Access-Control-Allow-Origin 不能设为 *(通配符),否则浏览器会拒绝跨域(违反 CORS 规范)。
后果:
如果前端请求时携带了 Cookie、Token 等凭证,浏览器会报如下错误:
plaintext
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
三、修复方案(根据你的实际需求选择)
方案 1:不需要携带凭证(大部分上传场景适用)
如果前端上传文件时不需要带 Cookie/Token,直接删除 Access-Control-Allow-Credentials: true,保留 * 通配符即可(最简单):
nginx
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
# 删掉这行:add_header 'Access-Control-Allow-Credentials' 'true' always;
方案 2:需要携带凭证(如登录态、Token)
如果前端必须携带 Cookie / 凭证,需将 Access-Control-Allow-Origin 设为 具体的允许域名 (不能用 *),同时保留 Credentials: true:
nginx
# 替换 * 为你的前端域名(如 https://www.xxx.com,注意不带 /)
add_header 'Access-Control-Allow-Origin' 'https://www.xxx.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
方案 3:允许多个域名携带凭证(进阶需求)
如果需要支持多个前端域名跨域且携带凭证,需用 Nginx 变量动态匹配请求源:
nginx
# 先定义允许的域名列表
map $http_origin $allow_origin {
~^https?://(www\.xxx\.com|admin\.xxx\.com)$ $http_origin; # 允许的域名
default ""; # 其他域名拒绝
}
# 再使用变量设置响应头
add_header 'Access-Control-Allow-Origin' $allow_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
四、补充:优化 OPTIONS 预检请求(可选但推荐)
跨域请求中,复杂请求(如带自定义头、POST 非 form-data 格式)会先发送 OPTIONS 预检请求。为了提升性能,可直接返回 204 状态码,无需转发到业务逻辑:
nginx
# 专门处理 OPTIONS 预检请求
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://www.xxx.com' always; # 与上面一致
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=utf-8';
return 204; # 成功且无响应体,提升性能
}
# 原有的静态文件配置...
root D:/platform/plaftform-plus/upload;
index index.html;
try_files $uri $uri/ =404;
}
# /upload 路径也建议添加 OPTIONS 处理,逻辑同上
location /upload {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://www.xxx.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=utf-8';
return 204;
}
# 原有的 alias、limit_except 等配置...
}
五、最终结论
- 修复
Access-Control-Allow-Origin: *与Credentials: true的冲突后,这份配置 能完美解决跨域问题; - 大部分文件上传场景不需要携带凭证,选择「方案 1」最简洁;
- 若需携带登录态 / Token,按「方案 2」或「方案 3」配置具体允许的域名;
- 补充 OPTIONS 预检请求处理,可提升跨域请求性能。