Apache-2.2

使用 .htaccess 對除一個路徑之外的每個 URL 強制使用 SSL

  • April 24, 2021

我正在嘗試對每個 URL 強制執行 SSL,但第一個 segment 除外/preview

http://test.example.com/preview/blah/blah

應該被規則忽略;應該強制所有其他 URL 使用 SSL。我正在使用 CentOS 6.4、Apache 和 CodeIgniter。

我的 .htaccess 文件:

RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/preview/
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]

通常 CI URL 在被最後一條規則重寫之前看起來像這樣:

http://test.example.com/index.php?/preview/blah/blah

我試過了:

RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/index.php?/preview/
RewriteCond %{REQUEST_URI} !^/preview/
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

那也行不通。我究竟做錯了什麼?

你幾乎擁有它。完整的解決方案是:

RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/preview
RewriteCond %{QUERY_STRING} !^/preview
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]

它失敗的原因是http://test.domain.com/preview/blah/blah首先被解析為http://test.domain.com/index.php?/preview/blah/blah並且該 URL 立即被再次重寫(htaccess 使用新 URL 循環)。

新 URL (http://test.domain.com/index.php?/preview/blah/blah不符合您的條件,因為 ? 之後的部分不被視為 REQUEST_URI 的一部分,而是 QUERY_STRING 的一部分。請參閱http://httpd.apache.org/docs/2.4/en上的 REQUEST_URI 描述/mod/mod_rewrite.html#rewritecond

引用自:https://serverfault.com/questions/646092