Mod_rewrite将/ var / www添加到结果URL

时间:2018-11-10 06:07:43

标签: apache .htaccess mod-rewrite

我对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 个答案:

答案 0 :(得分:1)

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]

您完全错过了 substitution 参数。 [L,R=404]将被视为替换字符串(并非预期的 flags )。这也将导致格式错误的重写/重定向。 RewriteRule应写为:

RewriteRule (.*) - [R=404]

请注意,将-(单个连字符)用作 substitution 参数(以后将被忽略)。指定非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]

请注意,我已经撤消了指令,以便在删除最后的尾部斜杠之前减少斜杠。

使用302s测试以避免缓存问题。并在测试之前清除浏览器缓存。

更新:如果URL的查询字符串部分曾经(正当)出现双斜杠,则由于 condition 在URL中的任意位置(包括查询字符串)中检查多个斜杠 ,而RewriteRule仅减少URL路径中的多个斜杠。如果您需要在查询字符串中允许多个斜杠,请将 CondPattern //+更改为\s[^?]*//+,以便仅检查URL路径,而不是整个URL。换句话说:

RewriteCond %{THE_REQUEST} \s[^?]*//+
RewriteRule (.*) /$1 [R=302,L]