Nginx 如何配置强制 HTTP 跳转 HTTPS 并保留原始请求参数
作者:drstx
最推荐的做法是在监听 80 端口的 server 块中使用 return 301 指令,配合 $request_uri 变量,这样既能实现永久跳转,又能原生保留路径和查询参数。
先说结论:这是 Nginx 官方推荐的标准写法,配置简单且对搜索引擎友好,适合绝大多数已部署 SSL 证书的生产环境。
- 适合:已拥有有效 HTTPS 证书,希望统一流量入口的站点
- 先准备:确认 443 端口服务正常,备份现有配置文件
- 验收:检查跳转状态码是否为 301,确认 URL 参数未丢失
命令速用版
如果你已经有一个可用的 HTTPS server 块,只需在配置文件中增加或修改监听 80 端口的 server 块,核心配置如下:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}这段配置会拦截所有 HTTP 请求,并原样跳转到对应的 HTTPS 地址。
为什么会这样
HTTP 是明文传输,存在数据被窃听或篡改的风险,强制跳转 HTTPS 是为了保障通信安全。使用 301 状态码是因为它代表“永久移动”,浏览器和搜索引擎会记住这个规则,后续请求会自动尝试 HTTPS,有利于 SEO 权重传递。
关于参数保留,Nginx 的 $request_uri 变量包含了客户端请求的完整 URI,包括路径和问号后面的查询参数(args)。相比之下,如果只用 $uri 可能会丢失参数,需要额外拼接 $args,而 $request_uri 是开箱即用的完整地址。
分步处理
1. 备份配置:在修改前务必备份当前配置文件,防止语法错误导致服务不可用。
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
2. 编辑配置:打开 Nginx 配置文件(通常在 /etc/nginx/conf.d/ 或 /etc/nginx/sites-enabled/),添加或修改监听 80 的 server 块。确保 server_name 与你的 HTTPS 配置一致。
3. 语法检查:修改完成后,先运行测试命令,确保没有拼写错误。
nginx -t
如果显示 successful,再进行下一步;如果报错,根据提示行号检查拼写。
4. 平滑重载:确认无误后,重载配置使改动生效,不会中断现有连接。
nginx -s reload
怎么验证是否生效
1. 命令行检查:使用 curl 命令查看响应头,确认状态码是 301 且 Location 指向 https。
curl -I http://example.com/?test=1
观察返回头中的 HTTP/1.1 301 Moved Permanently 和 Location: https://example.com/?test=1。
2. 浏览器验证:在地址栏输入 http 开头的带参数网址,观察地址栏是否自动变为 https,且参数部分保持不变。
3. 日志确认:查看 Nginx 访问日志,确认 80 端口的请求状态码记录为 301。
常见坑
1. 跳转死循环:如果 HTTPS 的 server 块配置错误,也可能把请求又转回 HTTP,导致浏览器报错“重定向次数过多”。确保 443 端口配置中不再有 return 301 http 的逻辑。
2. $host 变量获取异常:如果客户端请求直接使用的是 IP 地址,$host 可能是 IP。如果证书只绑定域名,HTTPS 握手可能会失败。建议 server_name 明确指定域名。
3. HSTS 影响:如果开启了 HSTS(HTTP Strict Transport Security),浏览器会强制记住 HTTPS 策略。在调试期间如果配置错误,可能需要清除浏览器缓存才能恢复 HTTP 访问。
4. 反向代理场景:如果 Nginx 前面还有负载均衡器或 CDN,需要在跳转逻辑中考虑 X-Forwarded-Proto 头,避免在内部网络重复跳转。
参考来源
- Nginx 官方文档 - ngx_http_rewrite_module 模块 return 指令说明
- Nginx 官方文档 - ngx_http_core_module 模块 内置变量说明
到此这篇关于Nginx 如何配置强制 HTTP 跳转 HTTPS 并保留原始请求参数的文章就介绍到这了,更多相关Nginx 强制 HTTP 跳转 HTTPS 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
