.htaccess:重定向删除文件扩展名,除非是查询字符串的一部分

时间:2016-02-07 17:21:04

标签: regex .htaccess redirect url-rewriting rewrite

这里的许多答案都很接近,但没有一个完整。

我希望.htaccess重定向并删除php / html扩展和尾部斜杠,以便所有文件,目录和引导看起来都一样。问题是URL可能包含或不包含带有外部URL链接的查询字符串,因此不应更改。

  1. 场景1:从简单网址中删除“.php”。
    • 这: examle.com/file.PHP
    • 成为: examle.com/file
  2. 场景2:从URL中删除“.php”但不从查询中删除。
    • 这: examle.com/file.PHP?link=anothersite.com/somefile.PHP
    • 成为: examle.com/file?link=anothersite.com/somefile.PHP
  3. 我有重写条件适用于一个或另一个场景但是找不到两者的单一解决方案。

    此条件适用于方案1但在方案2中失败,因为它还从查询字符串中的链接中剥离扩展名。

    RewriteCond %{THE_REQUEST} \/(.+)\.php
    

    这个(带有\?)适用于方案2,但只有在有查询(问号)时才有效,因此在方案1中失败。

    RewriteCond %{THE_REQUEST} \/(.+)\.php\?
    

    解决方案是一个正则表达式,它会查看整个字符串,除非有问号。或者可能以某种方式解析任何问号的字符串。我已经尝试在问号上放置一个“零或一个”限定符,但它引起了一个重定向循环。

    完成的代码与此类似。

    # Remove extensions shown in address bar
    RewriteCond %{THE_REQUEST} "\/(.+)\.(php|jar|html|shtml|htm) [NC]
    RewriteRule ^ /%1 [L,R=301]
    
    # Remove trailing slashes
    RewriteRule ^(.*)/$ /$1 [R=301,L]
    
    # Display php file if it exist 
    rewriteCond %{REQUEST_FILENAME}.php -f
    rewriteRule ^(.+)$ $1.php [L,QSA]
    

2 个答案:

答案 0 :(得分:2)

您可以使用此重定向规则使其适用于两个网址:

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

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [NE,R=302,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

答案 1 :(得分:1)

我已经为所有来到这里的人提供了最终的代码,其中包含与clean& amp;漂亮的网址。

以下代码应:

  1. 删除拖尾垃圾(斜线,问号,圆点等......)
  2. 隐藏不需要的扩展程序和索引
  3. 显示相关的index.php / filename.php
  4. 感谢anubhava提供所需的解决方案。

    RewriteEngine On
    Options -Multiviews -Indexes +FollowSymLinks   
    RewriteBase /
    DirectorySlash Off
    
    # Remove trailing question marks.
    RewriteCond %{THE_REQUEST} \?[\s?] [NC]
    RewriteRule ^(.*)$ /$1? [R,L]
    
    # Remove unwanted extensions, dots, "index", punctuation, trailing slash
    #   First condition group removed from anywhere in the path.
    #   Second condition group only removed from the end of the path.
    #   The rule will not alter text in the query. 
    RewriteCond %{THE_REQUEST} \s/+([^?]+?)\.(php|jar|html|shtml|htm)([^\s]*?)[\s?] [NC,OR]
    RewriteCond %{THE_REQUEST} \s/+([^?]+?)(\/index|\/|\.|,|\!])[\s?] [NC]
    RewriteRule ^ /%1%3 [R,NE,L]
    
    # If path points to a directory containing an index.php, use it
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteCond %{REQUEST_FILENAME}/index.php -f
    RewriteRule ^(.+)$ $1/index.php [L]
    
    # ElseIf path/filename points to a php file, use it
    RewriteCond %{REQUEST_FILENAME}.php -f
    RewriteRule ^(.+?)/?$ $1.php [L]
    
    ################################################################
    # Below here is only needed if you want a bootstrap
    # Without this, files will display or 404 as normal.
    ################################################################
    
    # If none of the above conditions are met, 
    # and the request is not an actual file (.jpg, .svg, etc.),
    # display the bootstrap file making the path
    # a query string for the bootstrap to parse.
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?strappath=$1 [QSA,L]
    

    谢谢,如果有错误或漏洞,请告诉我。