我对Apache mod_rewrite规则有一些问题。每当我尝试转到https://example.com//
(见末尾的双斜杠(时,它都会重定向到301页,但它添加了目录的位置,即https://example.com/var/www/my-domain.com/html
,这是不可取的。
这是我的.htaccess
文件:
ErrorDocument 404 /views/pages/404.php
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^www.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{THE_REQUEST} s/+(.*?)/+(/S+) [NC]
RewriteRule ^(.*) [L,R=404]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s/{2,} [NC]
RewriteRule ^(.*) $1 [R=301,L]
RewriteRule ^contact-us/?$ views/pages/contact.php [NC,L]
当我转到https://example.com//contact-us
时也会发生同样的情况。
CCD_ 5很好地重定向到CCD_ 6并且CCD_。
如果有人需要进一步的信息,请告诉我。
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s/{2,} [NC] RewriteRule ^(.*) $1 [R=301,L]
您在替换上缺少斜杠前缀。这导致相对路径替换(因为$1
反向引用不包含斜杠前缀(,mod_rewrite将目录前缀(即/var/www/example.com/html
(作为前缀。这将导致您看到的重定向格式不正确。RewriteRule
应写成:
RewriteRule (.*) /$1 [R=301,L]
(此处不需要RewriteRule
模式上的^
锚。(
但是,以下重定向也是无效的:
RewriteCond %{THE_REQUEST} s/+(.*?)/+(/S+) [NC] RewriteRule ^(.*) [L,R=404]
您完全缺少替换参数。[L,R=404]
将被视为替换字符串(而不是预期的标志(。这也会导致格式错误的重写/重定向。RewriteRule
应写成:
RewriteRule (.*) - [R=404]
请注意,-
(单连字符(用作替换参数(稍后将被忽略(。当指定非3xx响应代码时,会隐含L
标志。
然而,我很好奇你在这里试图做什么,因为你似乎在一个指令中"接受"多个斜杠(通过减少(,但在另一个指令(用404(中拒绝多个斜杠?为什么不减少URL路径中出现的所有多个斜杠序列?
例如,替换以下(修改后的代码(:
# Remove trailing slash from URL (except files and directories)
# >>> Why files? Files don't normally have trailing slashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Reject multiple slashes later in the URL or 3+ slashes at the start of the URL
RewriteCond %{THE_REQUEST} s/+(.*?)/+(/S+) [NC]
RewriteRule (.*) - [R=404]
# Reduce multiple slashes at the start of the URL
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s/{2,} [NC]
RewriteRule (.*) /$1 [R=301,L]
类似以下内容(取决于要求(:
# Reduce sequences of multiple slashes to a single slash in the URL-path
# NB: This won't work to reduce slashes in the query string (if that is an issue)
RewriteCond %{THE_REQUEST} //+
RewriteRule (.*) /$1 [R=302,L]
# Remove trailing slash from URL (except directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=302,L]
请注意,我已经颠倒了指令,以便在删除最后一个尾部斜杠之前减少斜杠。
使用302进行测试以避免缓存问题。并在测试前清除浏览器缓存。
更新:如果双斜杠可以(合法(出现在URL的查询字符串部分,则上述操作将导致重定向循环,因为条件会检查URL(包括查询字符串(中的任何位置是否有多个斜杠,而RewriteRule
只会减少URL路径中的多个斜杠。如果需要在查询字符串中允许多个斜杠,请将CondPattern从//+
更改为s[^?]*//+
,以专门检查URL路径,而不是整个URL。换句话说:
RewriteCond %{THE_REQUEST} s[^?]*//+
RewriteRule (.*) /$1 [R=302,L]