添加SSL证书后API调用失效问题求助
问题解决:HTTPS升级后API调用失败的排查与修复
问题根源
net::ERR_SSL_PROTOCOL_ERROR与微服务解析错误:SpringBoot微服务仅监听HTTP端口,但客户端通过HTTPS直接请求微服务端口,微服务无法解析HTTPS加密流量导致协议错误;同时微服务日志中的Invalid character found in method name,是因为它把HTTPS的加密请求头当成HTTP请求解析,自然无法识别。- 混合内容拦截:HTTPS页面被浏览器强制要求所有资源(包括API请求)都使用HTTPS,直接调用HTTP API会被拦截。
- Nginx配置缺失:当前配置仅将所有请求转发到Angular前端,未为API请求配置反向代理规则,导致API请求要么直接打向微服务的HTTP端口(触发SSL错误),要么用HTTP调用(触发混合内容拦截)。
修复步骤
1. 修改Nginx配置,添加API反向代理规则
假设你的API请求前缀为/api,在Nginx的server块中新增对应location规则,将API请求转发到SpringBoot微服务的HTTP端口(Docker Compose部署建议用服务名而非local_ip,保证容器间通信可靠):
server { server_name full_domain_name; # 处理Angular前端请求 location / { proxy_pass http://angular-service:4200/ ; # 替换为你的Angular服务名/地址 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } # 新增:处理API请求,转发到SpringBoot location /api/ { proxy_pass http://springboot-service:8080/api/ ; # 替换为你的微服务地址 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; # 告知微服务请求来自HTTPS } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/full_domain_name/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/full_domain_name/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } # Redirect HTTP to HTTPS server { if ($host = full_domain_name) { return 301 https://$host$request_uri; } listen 80; # HTTP server_name full_domain_name; return 404; # Managed by Certbot }
2. 调整Angular的API请求地址
将Angular中的API baseUrl改为相对路径(如/api),这样页面通过HTTPS访问时,API请求会自动使用HTTPS发送到Nginx,再由Nginx转发到SpringBoot的HTTP端口,彻底避免混合内容问题。
示例:在Angular的生产环境配置文件environment.prod.ts中修改:
export const environment = { production: true, apiBaseUrl: '/api' // 替换原有的http://local_ip:8080/api };
3. Docker Compose网络配置(若Nginx为容器)
确保Nginx、Angular、SpringBoot服务处于同一Docker网络,才能通过服务名互相访问。示例docker-compose.yml配置:
version: '3.8' services: angular-service: build: ./angular-app networks: - app-network springboot-service: build: ./springboot-app networks: - app-network nginx-service: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx/conf.d:/etc/nginx/conf.d - /etc/letsencrypt:/etc/letsencrypt # 挂载证书目录 networks: - app-network depends_on: - angular-service - springboot-service networks: app-network: driver: bridge
验证
- 重启Nginx或Docker Compose服务
- 访问HTTPS站点,检查API请求是否正常,客户端控制台无SSL或混合内容错误,微服务日志能正确接收并处理请求
内容的提问来源于stack exchange,提问作者steven stonie




