全站http跳https应使用return 301而非rewrite,更高效安全;需在listen 80的server块中添加return 301 https://$host$request_uri;,避免循环重定向、保留路径参数,并注意排除例外目录、重载配置及清除浏览器缓存。

全站HTTP跳HTTPS用 return 301,不是 rewrite
宝塔面板默认的「强制 HTTPS」开关底层就是加了 return 301,比 rewrite 更快、更安全。用 rewrite 容易触发循环重定向或匹配异常,尤其在有多个 location 块时。
直接在网站配置文件的 server 块(监听 80 端口部分)里加这一行即可:
return 301 https://$host$request_uri;
- 必须放在
listen 80的server块内,不能放在location /里 -
$request_uri保留原始路径和查询参数,$uri会丢掉 ? 后面的内容 - 不要写成
https://$server_name$request_uri——$server_name可能为空或不唯一,用$host更可靠
想排除某个目录(如 /api 或 /test)不跳 HTTPS?用 if + return 组合
宝塔不提供图形化“例外目录”功能,得手动改配置。核心思路是:只对不匹配指定路径的请求做跳转。
把原来那行 return 301 替换成:
if ($request_uri !~ ^/api/) {
return 301 https://$host$request_uri;
}
-
^/api/表示以/api/开头的路径,注意结尾斜杠——/api(无斜杠)和/apiv2都不会被排除 - 多个例外要写多个
if,Nginx 不支持||或正则 or 语法,比如排除/api和/static得这么写:
if ($request_uri !~ ^/api/ && $request_uri !~ ^/static/) {
return 301 https://$host$request_uri;
}
- 别用
set $flag拼字符串那种老方案——可读性差,且 Nginx 的if在location外行为不稳定,容易误判
为什么改完不生效?检查这三个地方
常见问题不是规则写错,而是环境没刷新或冲突没发现:
- 改完配置后必须点宝塔面板右上角「重载配置」,不是「重启 Nginx」——后者可能失败,而「重载」才真正 reload 配置
- 确认没在其他地方重复加跳转:比如「网站设置 → SSL → 强制 HTTPS」开着,又手动加了
return 301,会导致双跳甚至 301 套娃 - 浏览器缓存 301 很顽固,测试时用隐身窗口,或 curl 测试:
curl -I http://yoursite.com/test,看返回是不是301 Moved Permanently和Location:头
HTTPS 跳转后访问 HTTP 资源报 Mixed Content?那是前端问题,不是 Nginx 配置能解决的
即使 Nginx 全站跳 HTTPS,如果网页 HTML 或 JS 里写了 http://xxx.js 这种绝对 HTTP 地址,浏览器仍会拦截加载。Nginx 不处理响应体里的链接。
- 静态资源尽量用相对协议:
//cdn.example.com/jquery.js,或全用https:// - 后端渲染页面时,确保
url_for()、asset()等函数生成的是 HTTPS 链接(检查是否传了_scheme='https'或类似参数) - 宝塔里开「强制 HTTPS」只管请求入口,不管响应内容——这点容易被当成配置没生效











