error_page 497 是最轻量可靠的http→https跳转方式,因nginx原生识别该错误码,无需正则匹配、零运行时开销、避免循环重定向,且在ssl握手前即拦截非安全请求。

直接在 server 块中用 error_page 497 配合重定向,是最轻量、最可靠的 HTTP→HTTPS 跳转方式。它不依赖 rewrite 规则,不增加请求匹配开销,且由 Nginx 内核原生识别,响应更快、更稳定。
为什么选 error_page 497 而不是 rewrite?
当用户用 HTTP 访问本应只走 HTTPS 的 server(比如 listen 443 ssl; 但没配 listen 80),Nginx 会主动返回状态码 497 —— 这是 Nginx 自定义的“HTTP to HTTPS”错误码,专为此类场景设计。相比用 rewrite 判断 scheme 或 host 后 301 跳转,它:
- 无需正则匹配或变量判断,零运行时开销
- 避免 rewrite 潜在的循环重定向风险(如误配导致 / → / → /)
- 在 SSL 握手失败前就触发,更早拦截非安全请求
标准配置写法(推荐)
在仅监听 HTTPS 的 server 块中添加:
server {
listen 443 ssl;
server_name example.com;
<pre class="brush:php;toolbar:false;">ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 关键:捕获 497 并 301 重定向到 HTTPS 版本
error_page 497 =301 https://$host$request_uri;
# 其余配置……}
注意:不要在 listen 80 的 server 块里配这个;它只用于「本意只服务 HTTPS,但被 HTTP 访问」的场景。若需同时支持 80 端口并跳转,应另起一个纯 HTTP 的 server 块做 301,而非混用 497。
配合全局 http 块提升健壮性
为防止遗漏,可在 http 块中加一层兜底(可选):
http {
# 所有未显式处理 497 的 server,默认跳转
error_page 497 =301 https://$host$request_uri;
<pre class="brush:php;toolbar:false;"># 后续 server 块可继承,也可单独覆盖
server { … }}
这样即使新增 server 忘记配 497,也不会暴露 HTTP 响应。但要注意:若某 server 确实需要接受 HTTP(如健康检查端点),需在其内部显式覆盖:error_page 497 off;。
验证与常见问题
测试是否生效:
- 用 curl -I http://example.com —— 应返回 301 + Location: https://example.com/
- 浏览器访问 http://example.com —— 地址栏自动变为 https 版本
- 检查响应头中是否有
X-Frame-Options或Content-Security-Policy干扰跳转(极少见,但存在)
若跳转后出现证书错误,请确认:HTTPS server 的 server_name 与域名完全一致,且证书覆盖该域名(含 www / 非 www 变体)。











