https请求报错:The plain HTTP request was sent to HTTPS port
示例背景描述:
- www.test.com:11001服务需要对互联网使用https提供服务
- 后端java服务不支持https请求,且后端程序无法修改,仅支持http请求
问题描述:
- 因此在访问https://www.test.com:11001,URL会跳转http://www.test.com:11001,然后报错The plain HTTP request was sent to HTTPS port
报错如下:
解决思路:通过nginx代理
此处暂时将后端服务器设定为192.168.1.1,具体配置如下:
server {
listen 11001;
server_name localhost;
location / {
proxy_pass http://192.168.1.1:11001/;
proxy_set_header Host $host:$server_port; # 包含端口号防止丢失
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 https; # 强制设置协议为 HTTPS
proxy_set_header X-Forwarded-Port $server_port; # 传递端口
# 重定向修正
proxy_redirect ~^(http://[^:/]+)(:([0-9]+))?/(.*)$ https://$host:$server_port/$4;
proxy_redirect ~^(http://)([^/]+)/(.*)$ https://$host:$server_port/$3;
# 可选:日志调试
access_log /var/log/nginx/redirect_fix.log main;
error_log /var/log/nginx/redirect_error.log debug;
# 可选配置
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
}
# 可选配置
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
关键配置说明
1、proxy_redirect 正则表达式:
proxy_redirect ~^(http://[^:/]+)(:([0-9]+))?/(.*)$ https://$host:$server_port/$4;
- 匹配任何 HTTP 重定向:http://domain:port/path 或 http://domain/path
- 替换为:https://原始域名:11001/path
2、备用规则:
proxy_redirect ~^(http://)([^/]+)/(.*)$ https://$host:$server_port/$3;
- 匹配格式:http://anything/path
- 替换为:https://原始域名:11001/path
3、强制协议头部:
proxy_set_header X-Forwarded-Proto https;
- 即使后端服务不使用这个头部,也设置它以保持一致性
测试与验证方法
1、测试配置:
nginx -t
2、重载配置:
nginx -s reload
3、监控日志:
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
tail -f /var/log/nginx/redirect_fix.log
tail -f /var/log/nginx/redirect_error.log
4、重新访问测试
https://www.test.com:11001
常见问题排查表
问题现象 | 可能原因 | 解决方案 |
---|---|---|
重定向循环 | 后端服务也尝试重定向 | 检查后端响应是否已经是HTTPS |
端口号不正确 | 正则匹配失败 | 添加更通用的匹配规则 |
HTTPS证书错误 | 证书不匹配 | 检查SLB证书是否有效 |
404 错误 | 路径被修改 | 检查正则中的路径捕获组 如 $4 和 $3 |
如果上述配置仍有问题,使用这个更强大的版本:
proxy_redirect ~^http(://[^/]+)?(:\d+)?/(.*)$ https://$host:$server_port/$3;
proxy_redirect ~^http(://)([^/]+)/(.*)$ https://$host:$server_port/$3;
proxy_redirect default;
这个规则会:
- 匹配任何以 http 开头的重定向
- 替换为 https + 原始域名 + 11001端口
- 保留原始路径不变