我一直在为一个愚蠢的问题而苦恼,我相信有人已经问过这个问题,但我无法在这里或其他地方找到正确的答案。所以我开始吧。我已将 .htaccess 文件设置为将所有 http 请求重定向到 https。重写也已启用。一切似乎都运行良好,但是,当我使用 http 指定一个段时,网站会重定向到https://example.com/index.php。举例来说:
example.com -> redirects correctly to https://example.com
http://example.com -> redirects correctly
example.com/subdirectory -> redirects to https://example.com/index.php
http://example.com/subdirectory -> redirects to https://example.com/index.php
https://example.com/subdirectory -> redirects correctly
如果我之后使用导航链接https://exmaple.com加载,一切都很好。
我的重写和重定向规则如下:
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} (.+)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ %1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
我做错了什么?感谢您的时间,并感谢您的帮助。如果这是重复的,请原谅,并感谢您向正确的方向推动。谢谢。
答案1
让我们来看看:
- 你的第一条规则本质上设置了 HTTP:Authorization,这对于你的设置来说有些奇怪,但并不罕见……重要的是,没有
[L]
- 第二条规则规定,当您请求以 / 结尾但不是目录的 REQUEST_URI 时,您只会抓取该文件。如果匹配,您会进行外部重定向,然后我们又回到第一条规则 - 第二次遇到此规则时,我们应该会通过它。
- 第三条规则说,如果请求不是文件,并且请求不是目录,则内部路径应该转到 index.php,并且其他规则都不应该匹配
- 最后,你的规则捕获所有 http:// 并将外部重定向到 https://,在此过程中丢失了查询字符串
我不太明白发生了什么以及为什么会失败,但将最后一条规则移为第一条规则应该可以解决这个问题。
您可能还需要考虑切换 REQUEST_URI,因为您会丢失路径后的任何查询字符串。请将最后一行替换为以下内容:
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
这确保了:
http://example.com
没有斜杠https://example.com
- 任何字符 ( )重复零次或多次 ( )
.
后都会被放入组号 1/
*
- $1 添加到使用 HTTPS 协议的 URL 末尾
答案2
出于我不明白的原因,将 http 重定向移至 https 对我来说是有效的。所以我的文件现在看起来像这样。
RewriteEngine On
#Redirect from http to https
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
#as @LTPCGO suggested, I think I will change the above line to the one below. but i've included to show that it works for now.
#RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
但是,我注意到,如果我在 URL 中指定 index.php,例如,https://example.com/index.php/subdirectory,index.php 未被删除。因此我遵循了 @Frédéric Klee 的答案(Symfony 2 的做法),可在此处找到https://stackoverflow.com/questions/9608366/remove-index-php-from-url-with-htaccess。所以我的规则现在看起来是这样的,
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by apache
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/index.php [L]
谢谢 @长春市人民政府非常感谢您的回复。