
我只想將我的基本網域 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 就可以正常工作,但如果我訪問預期的常規 http,我將不會被重定向。如果我確實將該語句放入 http 區塊中,那麼一切都會在幾分鐘內停止工作。它可能適用於一些請求,但總是會在一分鐘左右停止。在瀏覽器中,我只得到一個包含所有請求的空白頁面。如果我重新啟動 nginx,它將繼續無法運作,直到我刪除 https 和 http 區塊中的兩個 if 語句區塊並重新啟動 nginx。當我查看錯誤日誌時,我沒有看到任何記錄。當我查看訪問日誌時,我看到以下訊息:
"-" 400 0 "-" "-"
我認為這意味著 400 錯誤。我不明白為什麼這對我不起作用。我的最終目標是讓基本網域僅支援 https,而所有其他頁面預設為 http。我怎樣才能實現這個目標?
答案1
我最終將 $uri 更改為 $request_uri,以便可以在沒有重定向循環的情況下處理 args。
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 語句來處理其他重寫,然後所有特定的服務都在這些語句下面完成。當我嘗試按照克里斯托弗的建議或我最初在問題中提出的方式處理所有內容時,可能只是我的特定配置導致重定向循環和錯誤。
答案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;
}
}
這是未經測試的,可能會出現錯誤,但應該可以工作