Forcing the rewriting of URLs by hiding .php AND .htm(l) extensions and redirecting to extensionless URLs

前端 未结 2 1232
再見小時候
再見小時候 2021-01-26 15:18

here is my configuration:

  • http://domain.com (obviously fictitious name...) hosted on a server running Apache with mod_rewrite enabled
  • folder named \"foo\"
相关标签:
2条回答
  • 2021-01-26 16:11

    I would like thank Everybody for this post as it really helped me a lot and I used something like the one below and works for me ...

    Options +FollowSymLinks  -MultiViews
    RewriteEngine on
    RewriteBase /
    
    RewriteCond %{ENV:REDIRECT_END}  =1
    RewriteRule ^ - [L,NS]
    
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^(.*?)\.(php|html?)$        $1   [R=301,NC,NS]
    
    RewriteCond %{REQUEST_FILENAME}\.html -f
    RewriteRule (.*)$ $1.html   [L,E=END:1,NS]
    
    RewriteCond %{REQUEST_FILENAME}\.htm -f
    RewriteRule (.*)$ $1.htm    [L,E=END:1,NS]
    
    RewriteCond %{REQUEST_FILENAME}\.php -f
    RewriteRule (.*)$ $1.php    [L,E=END:1,NS]
    

    This version works for me.

    Thank you.

    Cheers!

    0 讨论(0)
  • 2021-01-26 16:17

    There's a logic flaw in the first two rules in that it's the php or html file that exists. The URI check is also in effect a duplicate of the rewrite rule pattern and !f implies !-d. You can also fold these into a single rule:

    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^(.*?)\.(php|html?)$        $1   [R=301,NC]
    

    The last two are OK, but I'd swap the order if html requests are more common than php

    Why MultiViews doesn't help

    Options +MultiViews implements a concept known as content negotiation, and in doing this Apache invokes a subquery to parse the filename root name. One of the things that it does is to scan the directory for known filename.extension combinations so in this case if xxx.php exists and your request is for xxx then it will substitute xxx.php and do an internal redirection, which then causes your first rule to fire, removing the .php extension and this causes the error that you see.

    So (i) you need to disable multiviews, and (ii) ditto subqueries; (iii) detect and prevent retry loops. This is one solution which will do what you want:

    Options +FollowSymLinks  -MultiViews
    RewriteEngine on
    RewriteBase /foo
    
    RewriteCond %{ENV:REDIRECT_END}  =1
    RewriteRule ^ - [L,NS]
    
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^(.*?)\.(php|html?)$        $1   [R=301,NC,NS]
    
    RewriteCond %{REQUEST_FILENAME}\.html -f
    RewriteRule (.*)$ $1.html   [L,E=END:1,NS]
    
    RewriteCond %{REQUEST_FILENAME}\.htm -f
    RewriteRule (.*)$ $1.htm    [L,E=END:1,NS]
    
    RewriteCond %{REQUEST_FILENAME}\.php -f
    RewriteRule (.*)$ $1.php    [L,E=END:1,NS]
    
    0 讨论(0)
提交回复
热议问题