删除多个尾随斜杠 mod_rewrite
Posted
技术标签:
【中文标题】删除多个尾随斜杠 mod_rewrite【英文标题】:remove multiple trailing slashes mod_rewrite 【发布时间】:2011-02-20 05:35:55 【问题描述】:我知道这个问题仅在这个网站上就被问过很多次,但是浏览相关帖子我找不到解决方案。尝试在域后删除多个尾随斜杠。以下 mod_rewrite 表达式似乎适用于http://www.domain.com//path1///path2//// 等 URL,但不适用于域//
DirectorySlash Off
RewriteEngine on
# Canonical fix
RewriteCond %HTTP_HOST !^www.domain.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301]
RewriteRule ^/main.do http://www.domain.com/ [R=301,L]
RewriteRule ^/index.jsp http://www.domain.com/ [R=301,L]
# Remove bogus query strings
RewriteCond %query_string q= [NC]
RewriteRule (.*) http://www.domain.com/$1? [R=301,L]
# Remove multiple slashes after domain - DOESN'T WORK!!!
#RewriteCond %REQUEST_URI ^//+(.*)$ [OR]
#RewriteCond %REQUEST_URI ^(.*/)/+$
#RewriteRule / http://www.domain.com/%1 [R=301,L]
# Remove multiple slashes anywhere in URL
RewriteCond %REQUEST_URI ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
# Externally redirect to get rid of trailing slash except for home page, ads
RewriteCond %REQUEST_URI !^/ads/
RewriteRule ^(.+)/$ $1 [R=301,L]
【问题讨论】:
但是 'domain//' 不是一个有效的 URI?!?,因为 'domain' 不是 TLD 格式。如果这是内部设置,请使用 domain.lan 或者如果您的意思是“localhost//”,则在您的主机文件中添加一个条目。 艾登,我不允许发布多个 URL,因此我必须缩写。澄清 domain.com// 不起作用。感谢您抽出宝贵时间回复,博彦 对于最短的解决方案,请查看 Gerben 对此问题的回答。 ***.com/questions/8460015/… 【参考方案1】:无法复制。域之后的额外斜杠永远不会传递给 mod_rewrite,即使 DirectorySlashes 关闭——我还没有检查是 Opera 还是 Apache 删除了斜杠)。但除此之外,一切正常:
RewriteBase /
RewriteCond %REQUEST_URI ^//+(.*)$ [OR]
RewriteCond %REQUEST_URI ^(.*/)/+$
RewriteRule .* http://domain/%1 [R=301,L]
请求http://localhost//abc/b//
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (3) [perdir C:/HTTP/htdocs/] add path info postfix: C:/HTTP/htdocs/abc -> C:/HTTP/htdocs/abc/b/
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (3) [perdir C:/HTTP/htdocs/] strip per-dir prefix: C:/HTTP/htdocs/abc/b/ -> abc/b/
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (3) [perdir C:/HTTP/htdocs/] applying pattern '.*' to uri 'abc/b/'
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (4) [perdir C:/HTTP/htdocs/] RewriteCond: input='/abc//b//' pattern='^//+(.*)$' => not-matched
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (4) [perdir C:/HTTP/htdocs/] RewriteCond: input='/abc//b//' pattern='^(.*/)/+$' => matched
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (2) [perdir C:/HTTP/htdocs/] rewrite 'abc/b/' -> 'http://domain//abc//b/'
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (2) [perdir C:/HTTP/htdocs/] explicitly forcing redirect with http://domain//abc//b/
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (1) [perdir C:/HTTP/htdocs/] escaping http://domain//abc//b/ for redirect
127.0.0.1 - - [17/May/2010:12:26:36 +0100] [localhost/sid#c08fb0][rid#2756540/initial] (1) [perdir C:/HTTP/htdocs/] redirect to http://domain//abc//b/ [REDIRECT/301]
注意:考虑不要对主机进行硬编码:
RewriteCond %HTTP_HOST !=""
RewriteCond %REQUEST_URI ^//+(.*)$ [OR]
RewriteCond %REQUEST_URI ^(.*/)/+$
RewriteRule .* http://%HTTP_HOST/%1 [R=301,L]
还要注意内部的“//”没有被替换。您将添加另一个规则来替换内斜线。
新编辑: 好的,这似乎可以防止 URL 以 //:
开头或结尾RewriteEngine on
RewriteBase /
RewriteCond %HTTP_HOST !=""
RewriteCond %THE_REQUEST ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %THE_REQUEST ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%HTTP_HOST/%1 [R=301,L]
【讨论】:
Artefacto,localhost//abc//b// 可以正常工作,localhost// 不行。感谢 %HTTP_HOST 提示。我已经列出了表达式以及日志的摘录。 # 删除域后的多个斜杠 - 仍然不起作用!!! RewriteCond %HTTP_HOST !="" RewriteCond %REQUEST_URI ^//+(.*)$ [OR] RewriteCond %REQUEST_URI ^(.*/)/+$ RewriteRule .* http://%HTTP_HOST /%1 [R=301,L] RewriteCond %REQUEST_URI ^(.*)//(.*)$ RewriteRule 。 %1/%2 [R=301,L] 127.0.0.1 - - [18/May/2010:06:13:19 -0700] "GET /// HTTP/1.1" 200 10626 谢谢,博彦 也许它可以使用 THE_REQUEST 而不是 REQUEST_URI。我回家后会检查一下 第一个解决方案不适用于域后的双斜杠,但适用于结束域的双斜杠。对我来说,使用 THE_REQUEST 的解决方案适用于这两种情况。使用 rewriteloglevel 9 发布您的重写日志。【参考方案2】:以下是似乎有效的完整清单:
DirectorySlash Off
RewriteEngine on
# Fix Canonical URLs
RewriteCond %HTTP_HOST !^www.domain.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301]
RewriteRule ^/main.do http://www.domain.com/ [R=301,L]
RewriteRule ^/index.jsp http://www.domain.com/ [R=301,L]
# Remove bogus query strings
RewriteCond %HTTP_HOST !=""
RewriteCond %query_string q= [NC]
RewriteRule (.*) http://%HTTP_HOST/$1? [R=301,L]
# Remove multiple slashes after domain
RewriteCond %HTTP_HOST !=""
RewriteCond %THE_REQUEST ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %THE_REQUEST ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%HTTP_HOST/%1 [R=301,L]
# Remove multiple slashes anywhere in URL
RewriteCond %REQUEST_URI ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
# Externally redirect to get rid of trailing slash except for home page and ads
RewriteCond %REQUEST_URI !^/ads/
RewriteRule ^(.+)/$ $1 [R=301,L]
【讨论】:
【参考方案3】:您是在告诉 Apache 将包括第一个斜杠在内的所有内容映射到 $1
RewriteRule ^(.*)$ domain/$1 [R=301]
RewriteRule (.*) domain/$1? [R=301,L]
RewriteRule ^(.+)/$ $1 [R=301,L]
在插入符号后添加一个斜杠或在您的域名后删除一个斜杠
【讨论】:
【参考方案4】:以下代码将去除所有多余的斜杠,包括域后的多余斜杠。
RewriteCond %THE_REQUEST //
RewriteRule ^(.*)$ /$1 [L,R=301]
【讨论】:
【参考方案5】:这个在发送重定向之前删除了所有的斜线
# if match set environment variable and start over
RewriteRule ^(.*?)//+(.*)$ $1/$2 [E=REDIR:1,N]
# if done at least one. redirect with 301
RewriteCond %ENV:REDIR 1
RewriteRule ^/(.*) /$1 [R=301,L]
【讨论】:
以上是关于删除多个尾随斜杠 mod_rewrite的主要内容,如果未能解决你的问题,请参考以下文章