《Nginx CORS配置:解决跨域资源共享问题》

VIP/
跨域资源共享(CORS,Cross-Origin Resource Sharing)是现代Web开发中常见的技术挑战。当浏览器从一个域名的网页去请求另一个域名的资源时,就会触发跨域限制。这是浏览器出于安全考虑实施的同源策略(Same-Origin Policy)导致的。
同源策略要求协议、域名、端口三者完全相同才被认为是同源。例如:
  • https://web.example.com访问 https://api.example.com→ 跨域(域名不同)
  • http://localhost:3000访问 http://localhost:8080→ 跨域(端口不同)
  • http://example.com访问 https://example.com→ 跨域(协议不同)
直观表现是浏览器控制台会报错:”CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource”。

二、Nginx解决跨域的核心原理

Nginx通过反向代理机制解决跨域问题。核心思路是:前端不直接请求后端API,而是请求和自己同源的Nginx服务器。Nginx作为中间层,将请求转发给后端(服务器间通信没有跨域限制),然后在响应中添加允许跨域的HTTP头部信息,再返回给前端,从而绕过浏览器的跨域拦截。

三、Nginx CORS基础配置

3.1 最简单的配置(允许所有域名)

适用于开发测试环境,生产环境不推荐使用:
server {
    listen 80;
    server_name example.com;
    
    location / {
        # 允许所有域名跨域
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        
        # 处理OPTIONS预检请求
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }
        
        # 其他配置
        proxy_pass http://backend;
    }
}

3.2 配置说明

  • Access-Control-Allow-Origin:允许跨域的域名,*表示允许所有域名
  • Access-Control-Allow-Methods:允许的HTTP方法(如GET、POST等)
  • Access-Control-Allow-Headers:允许的请求头
  • Access-Control-Expose-Headers:允许客户端访问的响应头
  • Access-Control-Max-Age:预检请求的缓存时间(单位:秒)
  • OPTIONS请求处理:用于处理浏览器的预检请求(Preflight Request)

四、不同场景的配置模板

4.1 生产环境配置(指定单个前端域名)

最安全的配置方式,仅允许自家前端域名跨域:
server {
    listen 80;
    server_name localhost;
    
    location /api {
        # 后端真实地址
        proxy_pass http://127.0.0.1:8081;
        
        # 允许跨域的前端域名
        add_header Access-Control-Allow-Origin https://www.yourdomain.com;
        add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Allow-Headers *;
        add_header Access-Control-Max-Age 3600;
    }
}

4.2 测试环境配置(允许所有域名)

适用于本地开发、测试环境:
server {
    listen 80;
    server_name localhost;
    
    location /api {
        proxy_pass http://127.0.0.1:8081;
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Allow-Headers *;
        add_header Access-Control-Max-Age 3600;
    }
}
注意:生产环境绝对禁止使用Access-Control-Allow-Origin: *,避免数据泄露风险。

4.3 带登录态的配置(需要携带Cookie)

适用于需要传递登录态(Cookie/Session)的接口:
server {
    listen 80;
    server_name localhost;
    
    location /api {
        proxy_pass http://127.0.0.1:8081;
        
        # 必须指定具体域名,不能是*
        add_header Access-Control-Allow-Origin https://www.yourdomain.com;
        add_header Access-Control-Allow-Credentials true;  # 允许携带Cookie的核心配置
        add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Allow-Headers *;
        add_header Access-Control-Max-Age 3600;
    }
}
前端配合
  • Axios:axios.get('/api/xxx', { withCredentials: true })
  • Fetch:fetch('/api/xxx', { credentials: 'include' })

4.4 复杂请求配置(含PUT/DELETE、JSON数据)

适用于前端发送非简单请求的情况:
server {
    listen 80;
    server_name localhost;
    
    location /api {
        proxy_pass http://127.0.0.1:8081;
        
        # 专门处理OPTIONS预检请求
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin https://www.yourdomain.com;
            add_header Access-Control-Allow-Methods *;
            add_header Access-Control-Allow-Headers *;
            add_header Access-Control-Max-Age 3600;
            return 204;  # 预检请求无需返回内容,直接允许
        }
        
        # 正常请求的跨域配置
        add_header Access-Control-Allow-Origin https://www.yourdomain.com;
        add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Allow-Headers *;
    }
}

五、允许多个域名跨域

Nginx原生不支持直接配置多个域名,但可以通过map指令和条件判断实现:
# 定义允许的域名
map $http_origin $cors_origin {
    default "";
    "~^https://example.com$" $http_origin;
    "~^https://another.com$" $http_origin;
    "http://localhost:3000" $http_origin;
    "http://localhost:8080" $http_origin;
}

server {
    listen 80;
    server_name example.com;
    
    location / {
        # 动态设置允许的域名
        add_header 'Access-Control-Allow-Origin' $cors_origin;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        
        # 处理OPTIONS预检请求
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }
        
        proxy_pass http://backend;
    }
}

六、配置步骤与测试

6.1 配置步骤

  1. 定位配置文件:Nginx主配置文件通常位于/etc/nginx/nginx.conf/usr/local/nginx/conf/nginx.conf
  2. 编辑配置:在server块内的location块中添加CORS相关配置
  3. 保存并重启
    sudo nginx -t          # 测试配置文件语法
    sudo nginx -s reload   # 重新加载配置
    # 或
    sudo systemctl restart nginx  # 重启Nginx服务

6.2 测试验证

使用curl命令检查响应头:
curl -I https://example.com
确保响应头中包含Access-Control-Allow-Origin等相关字段。
也可以在浏览器开发者工具中查看网络请求,确认CORS头部信息是否正确。

七、安全注意事项

  1. 限制域名:生产环境应限制为特定的可信域名,避免使用*通配符
  2. 凭证安全:当需要携带凭证(如Cookies)时,Access-Control-Allow-Origin不能设置为*,必须指定具体域名
  3. 缓存问题:如果配置了Access-Control-Allow-Origin为具体域名,确保客户端不会缓存错误的响应头
  4. 预检请求:对于复杂请求(如Content-Type: application/json),浏览器会先发送OPTIONS预检请求,确保Nginx正确处理
  5. 使用always参数:建议在add_header指令后添加always参数,确保所有响应状态(包括4xx错误)都返回CORS头

八、常见问题排查

  1. 配置后仍报错
    • 检查Nginx端口和前端是否同源
    • 确认proxy_pass是否正确指向后端地址
    • 检查前端接口路径是否与Nginx配置的location匹配
  2. OPTIONS请求未正确处理
    • 确保配置中包含对$request_method = 'OPTIONS'的处理
    • 预检请求应返回204状态码
  3. Cookie无法携带
    • 确认Access-Control-Allow-Origin设置为具体域名而非*
    • 添加Access-Control-Allow-Credentials: true头部
    • 前端请求需设置withCredentials: true

九、总结

通过Nginx配置CORS是解决跨域问题的有效方案。根据实际需求,可以选择允许所有域名、特定域名或多个域名跨域访问。开发环境可以使用宽松配置快速调试,生产环境则应严格限制访问来源,确保系统安全。
合理配置CORS不仅能解决跨域问题,还能提升Web应用的安全性和用户体验。建议根据项目实际需求,选择合适的配置方案,并在部署前充分测试验证。

购买须知/免责声明
1.本文部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
2.若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
3.如果本站有侵犯、不妥之处的资源,请在网站右边客服联系我们。将会第一时间解决!
4.本站所有内容均由互联网收集整理、网友上传,仅供大家参考、学习,不存在任何商业目的与商业用途。
5.本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
6.不保证任何源码框架的完整性。
7.侵权联系邮箱:aliyun6168@gail.com / aliyun666888@gail.com
8.若您最终确认购买,则视为您100%认同并接受以上所述全部内容。

免费源码网 Nginx 《Nginx CORS配置:解决跨域资源共享问题》 https://svipm.com.cn/21361.html

上一篇:

已经没有上一篇了!

相关文章

猜你喜欢