我对 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
https://example.com/contact-us//
成功重定向https://example.com/contact-us
至https://example.com//contact-uss
404 页面。
如果需要更多信息,请告诉我。
答案1
复制自我在 StackOverflow 上的回答同一问题:
https://stackoverflow.com/questions/53236444/mod-rewrite-is-adding-var-www-to-the-resulting-url
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} \s[^?]*//+
RewriteRule (.*) /$1 [R=302,L]
# Remove trailing slash from URL (except directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=302,L]
请注意,我已经反转了指令,以便在删除最后的尾随斜杠之前减少斜杠。
请注意,正则表达式\s[^?]*//+
专门检查 URL 路径中的多个斜杠,不包括查询字符串。如果可能出现多个斜杠,这一点很重要合法地发生在请求参数,因为该RewriteRule
指令仅减少 URL 路径中的多个斜杠。否则您将陷入重定向循环。
使用 302 进行测试以避免缓存问题。并在测试前清除浏览器缓存。