在 nginx 中实现 http 跳转 https,最标准且高效的做法是在监听 80 端口的 server 块中使用 return 301 指令。通过配置 $scheme、$host 和 $request_uri 变量,nginx 会直接返回 301 永久重定向响应,将客户端引导至 https 地址,整个过程无需启动正则引擎,性能开销极低。

如何配置监听 80 端口的 Server 块以触发重定向
要实现跳转,必须确保 Nginx 有一个专门处理 HTTP 流量的 server 块,其 listen 指令明确指定端口为 80。在该块内部,只需添加一行 return 301 https://$host$request_uri; 即可生效。当请求进入此块时,Nginx 会立即构造重定向响应并结束处理流程,不会继续匹配后续的 location 或执行复杂的 rewrite 规则。这种配置方式适用于所有需要强制启用 HTTPS 的场景,是替代旧式 rewrite ^(.*)$ https://$host$1 permanent; 的首选方案。

server {
listen 80;
server_name example.com www.example.com;
# 直接返回 301 跳转到 HTTPS
return 301 https://$host$request_uri;
}
上述配置中,server_name 定义了该规则适用的域名。如果用户通过 IP 地址访问,由于没有匹配的 server_name,可能会落入默认 server 块。因此,通常建议将未绑定的默认 server 块也设置为返回 444 或类似的错误码,以拒绝非法请求。对于 example.com 的访问者,浏览器会收到状态码 301,并在 Location 头中看到新的 HTTPS URL,随后自动发起新请求。
为什么推荐使用 return 而非 rewrite 进行跳转
虽然 rewrite 指令也能实现跳转,但在简单的 HTTP 到 HTTPS 切换场景中,return 指令具有显著优势。rewrite 需要依赖正则表达式引擎来解析 URI,这会引入额外的 CPU 计算开销。而 return 是 Nginx 的核心指令之一,它直接在配置解析阶段确定动作,跳过了正则匹配过程。对于高并发场景,使用 return 301 可以减少服务器端的处理延迟,提升整体吞吐量。此外,return 的语法更简洁,意图更明确,降低了配置出错的可能性。

# 不推荐的旧式写法
server {
listen 80;
server_name example.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
# 推荐的现代写法
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
对比两段代码,旧式写法中的 permanent 关键字等同于 return 301,但前面的 rewrite 规则仍然会被执行。在现代 Nginx 版本中,官方文档明确建议使用 return 来处理此类简单的重定向逻辑。除非你需要根据特定的 URI 模式进行条件判断(例如仅对某些路径跳转),否则不应使用 rewrite。保持配置的简洁性有助于后续维护和故障排查。
当请求包含自定义端口时跳转行为如何表现
在使用 $host 变量时,需要注意其默认行为不包含端口号。如果原始 HTTP 请求是通过非标准端口(如 8080)发出的,直接使用 $host 会导致跳转后的 URL 丢失端口信息,从而可能指向默认的 443 端口,造成连接失败。此时,应使用 $http_host 变量,它会保留原始请求中的主机名和端口号。这样可以确保无论用户通过何种端口访问,都能被正确重定向到对应的 HTTPS 端口。
server {
listen 8080;
server_name example.com;
# 使用 $http_host 保留原始端口
return 301 https://$http_host$request_uri;
}
在这个示例中,如果用户访问 http://example.com:8080/page,Nginx 会返回 301 重定向到 https://example.com:8080/page。这要求你的 HTTPS server 块也必须监听 8080 端口,或者你希望用户在跳转后手动修改端口。通常情况下,HTTPS 服务运行在标准的 443 端口,因此大多数场景下直接使用 $host 即可。但如果你的架构特殊,使用了非标准端口,务必验证 $http_host 的行为是否符合预期。


















