我只希望将我的基本域名 www.domain.com 重写为https://www.domain.com 默认情况下,在我的 https 块中,如果它不是 ~uri =“/”(基本域)或静态内容,我会将其重新路由到 http://。
server {
listen 443;
set $ssltoggle 2;
if ($uri ~ ^/(img|js|css|static)/) {
set $ssltoggle 1;
}
if ($uri = '/') {
set $ssltoggle 1;
}
if ($ssltoggle != 1) {
rewrite ^(.*)$ http://$server_name$1 permanent;
}
}
因此,在我的 http 块中,如果必须使用 https,则需要进行重写:
server {
listen 80;
if ($uri = '/') {
set $ssltoggle 1;
}
if ($ssltoggle = 1) {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
}
如果我在 http 块中没有 $uri = '/' if 语句,那么直接转到 https 时,https 可以正常工作,但如果我转到常规 http,则不会被重定向,这是预料之中的。如果我在 http 块中放入该语句,那么一切都会在几分钟内停止工作。它可能会适用于一些请求,但总会在一分钟左右停止。在浏览器中,对于所有请求,我只会得到一个空白页。如果我重新启动 nginx,它将继续不起作用,直到我删除 https 和 http 块中的 if 语句块并重新启动 nginx。当我查看错误日志时,我没有看到任何记录。当我查看访问日志时,我看到此消息:
"-" 400 0 "-" "-"
我认为这意味着 400 错误。我不明白为什么这对我来说不起作用。我的最终目标是让基本域仅使用 https,而所有其他页面默认为 http。我该如何实现这一点?
答案1
我最终将 $uri 更改为 $request_uri,这样就可以处理参数而无需重定向循环。
server {
listen 443;
set $ssltoggle 2;
if ($uri ~ ^/(img|js|css|static)/) {
set $ssltoggle 1;
}
if ($request_uri = '/') {
set $ssltoggle 1;
}
if ($ssltoggle != 1) {
rewrite ^(.*)$ http://$server_name$1 permanent;
}
}
然后我改变了 http 块,如果位置= / 则立即重写
server {
listen 80;
location = / {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
if ($ssltoggle = 1) {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
}
我仍有 IF 语句来处理其他重写,然后所有特定的服务都在这些语句下面完成。当我尝试按照 Christopher 的建议或我最初在问题中提出的方式处理所有事情时,可能只是我的特定配置导致了重定向循环和错误。
答案2
您不需要所有的 if 语句。您应该使用位置语句。
server {
listen 80;
#rewrite base (/) to ssl
location = / {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
#serve anything else
location / {
[serve non-ssl page ...]
}
}
server {
listen 443;
#serve base url
location = / {
[serve ssl page ...]
}
#serve assets
location ~ ^/(img|js|css|static)/ {
[serve ssl assets ...]
}
#rewrite anything else
location / {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
}
这未经测试,可能会出现错误,但应该可以工作