一、问题/场景描述
在前后端分离的Web项目中,前端应用通过HTTPS协议访问部署在不同域名或端口的后端API时,浏览器会因同源策略而拦截请求,即使后端已启用SSL。这导致控制台出现跨域错误,API调用失败,影响应用正常功能。
二、原因分析
该问题的核心在于浏览器的同源安全策略。当请求的协议、域名、端口任一不同,即被视为跨域请求。在HTTPS环境下,即使Nginx已配置SSL证书,若未在响应头中明确设置允许跨域的相关指令,浏览器仍会阻止来自前端页面的请求。这通常表现为CORS(跨源资源共享)错误。因此,需要在Nginx的SSL服务器配置块中,同时处理SSL连接和添加跨域响应头,两者缺一不可。
三、详细解决步骤
以下步骤将指导您在Nginx配置中同时启用SSL并解决跨域问题。
步骤1:定位并编辑Nginx配置文件
首先,找到您的Nginx站点配置文件,通常位于 /etc/nginx/sites-available/ 或 /etc/nginx/conf.d/ 目录下。使用文本编辑器打开对应文件。
sudo nano /etc/nginx/sites-available/your_domain.conf
步骤2:配置SSL证书与基础参数
在 server 块中配置SSL证书路径、协议版本等基础参数。请将 ssl_certificate 和 ssl_certificate_key 的路径替换为您自己的证书文件路径。
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
# SSL 配置
ssl_certificate /path/to/your/fullchain.pem;
ssl_certificate_key /path/to/your/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 其他配置...
}
步骤3:添加跨域响应头
在同一个 server 块中,通常在 location 块内(例如处理API请求的 location /api/)或直接在 server 块内,添加关键的CORS响应头。以下配置允许来自 https://www.yourdomain.com 的所有跨域请求,并支持常见的请求方法和头信息。
location / {
# 设置允许跨域的源,可指定具体域名或使用通配符‘*’(不推荐在生产环境使用)
add_header 'Access-Control-Allow-Origin' 'https://www.yourdomain.com' always;
# 允许客户端携带的请求头
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;
# 允许的HTTP方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
# 允许浏览器暴露响应头给前端JavaScript
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;
# 对于OPTIONS预检请求,直接返回204
if ($request_method = 'OPTIONS') {
return 204;
}
# 您的代理转发或根目录配置,例如:
# proxy_pass http://backend_server;
# 或 root /var/www/html;
}
步骤4:测试配置并重载Nginx
保存配置文件后,首先使用 nginx -t 命令测试配置文件语法是否正确。
sudo nginx -t
如果显示“syntax is ok”和“test is successful”,则说明配置无误。然后重载Nginx使配置生效。
sudo systemctl reload nginx
四、注意事项
配置时需注意:生产环境中 Access-Control-Allow-Origin 应尽可能指定具体的前端域名,避免使用通配符‘*’,尤其是当请求携带Cookie等凭证信息时。若需携带凭证,则必须指定具体域名,且需添加 Access-Control-Allow-Credentials: true 头。同时,确保SSL证书有效且配置路径正确。
