.htaccess 中的 mod_rewrite 规则顺序未得到遵循

.htaccess 中的 mod_rewrite 规则顺序未得到遵循

我们正在尝试对某些 URL 强制实施 HTTPS,而对其他 URL 强制实施 HTTP。我们还在重写 URL,以便所有请求都通过我们的 index.php。这是我们的 .htaccess 文件。

# enable mod_rewrite
RewriteEngine on

# define the base url for accessing this folder
RewriteBase /

# Enforce http and https for certain pages
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# rewrite all requests for file and folders that do not exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?query=$1 [L,QSA]

如果我们不包含最后一条规则(RewriteRule ^(.*)$ index.php?query=$1 [L,QSA]),HTTPS 和 HTTP 规则可以完美运行;当我们添加最后三行时,我们的其他规则将停止正常工作。

例如,如果我们尝试转到 https://www.domain.com/en/customer/login,它会重定向到 http://www.domain.com/index.php?query=en/customer/login。

这就像在重定向完成之前和 [L] 标志之后应用最后一条规则一样,表示重定向是最后一条应用的规则。

更新

我们在所有规则中添加了 [NS] 标志,但没有什么区别。

答案1

您的前两个规则第一次命中,然后发出额外请求(因为 301),这将在重新进入时命中第三个 RewriteRule。请尝试以下方法:我为您的“checkout”路径添加了一个例外:

# enable mod_rewrite
RewriteEngine on

# define the base url for accessing this folder
RewriteBase /

# Enforce http and https for certain pages
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ index.php?query=$1 [L,QSA]

希望有帮助!

答案2

您期望什么行为?

https://site.com/en/customer/login 不会受到 .htaccess 中第一条或第二条规则的影响,并且由于 /en/customer/login 不是系统上的文件或目录,因此它将重写。

http://site.com/en/customer/login 会受到第一条规则的影响,并会被重定向到https://site.com/en/customer/login。由于它已被重定向,因此它现在是一个新的响应,不会受到 .htaccess 中的第一条或第二条规则的影响,并且会匹配最后一个测试(/en/customer/login 不存在作为文件或目录)并且它会重写。

http://site.com/en/somethingelse 不会受到第一条或第二条规则的影响,并且由于 /en/somethingelse 不存在,它会重写 url。

https://site.com/en/somethingelse 不会受到第一条规则的影响,将被重定向到http://site.com/en/somethingelse。由于它已被重定向,因此它是一个新的响应,不会受到 .htaccess 中的第一条或第二条规则的影响,并且会匹配最后一个测试(/en/somethingelse 不存在作为文件或目录)并且它会重写。

相关内容