Azure虚拟机CORS与服务器问题:Next.js前端调用API遇混合内容错误
解决Vercel前端调用Azure虚拟机API的Mixed Content问题
核心问题根源
自签名SSL证书不被浏览器默认信任,Vercel部署的HTTPS前端调用带自签名证书的API时,浏览器会拦截请求,导致Mixed Content Error(即使地址用了HTTPS,证书不可信也会触发类似拦截)。本地环境因为浏览器可能已手动信任证书,所以无问题。
解决方案步骤
1. 替换自签名证书为可信SSL证书
浏览器只信任受CA机构签发的证书,必须替换自签名证书为Let's Encrypt这类免费可信证书:
- 给虚拟机绑定一个域名(Let's Encrypt需要域名验证,无域名可申请免费域名或用动态域名服务),确保域名解析指向虚拟机公网IP。
- 在Azure虚拟机上安装
certbot,为Nginx申请Let's Encrypt证书:# 安装certbot和Nginx插件 sudo apt update && sudo apt install certbot python3-certbot-nginx # 申请证书并自动配置Nginx sudo certbot --nginx -d your-domain.com - 证书申请完成后,certbot会自动配置Nginx的SSL规则,同时开启证书自动续期。
2. 确保前端API请求全用HTTPS
检查Next.js代码中的API请求地址:
- 硬编码的base URL直接改为
https://your-domain.com/api(或https://121.112.20.7/api,但用域名更适合证书管理)。 - 推荐用Vercel环境变量管理API地址,在Vercel控制台配置
NEXT_PUBLIC_API_BASE_URL=https://your-domain.com/api,代码中通过process.env.NEXT_PUBLIC_API_BASE_URL调用,避免硬编码。
3. 优化Nginx反向代理配置
确保Nginx的SSL和CORS配置正确,示例配置如下:
server { listen 443 ssl; server_name your-domain.com 121.112.20.7; # 同时绑定域名和IP # Let's Encrypt证书路径(certbot自动生成) ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; # 安全的SSL协议和加密套件 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location /api { proxy_pass http://localhost:xxxx; # 替换为Docker容器的内部端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # CORS配置(与Express的CORS设置兼容) add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS; add_header Access-Control-Allow-Headers Content-Type,Authorization; # 处理OPTIONS预检请求 if ($request_method = OPTIONS) { return 204; } } } # 强制HTTP请求跳转HTTPS server { listen 80; server_name your-domain.com 121.112.20.7; return 301 https://$server_name$request_uri; }
配置完成后重启Nginx:sudo systemctl restart nginx
4. 验证网络与容器配置
- 确认Azure虚拟机的网络安全组(NSG)已添加入站规则:允许443端口(TCP),源地址设为
Any或Vercel的IP范围。 - 验证Docker容器端口映射正确,确保Nginx能访问到容器内的Express服务。
- 用浏览器访问
https://your-domain.com/api/xxx,确认无证书警告且API正常响应。
内容的提问来源于stack exchange,提问作者itsabdulkader
相关产品推荐
相关产品推荐

