通过隐藏的.php和.htm(L)扩展和重定向到无扩展名的URL强制的URL重写 [英] Forcing the rewriting of URLs by hiding .php AND .htm(l) extensions and redirecting to extensionless URLs
问题描述
下面是我的配置:
- http://domain.com (显然虚构的名字......)主办运行Apache的mod_rewrite与启用的服务器上
- 文件夹名为foo:(位于 http://domain.com/foo/ 并在我希望把我的.htaccess文件)只包含3种类型的文件.PHP,名为.htm或.html
- .php文件(为了这个例子,我会引用其中之一:phpfile.php)
- 在.htm文件(为了这个例子,我会引用其中之一:htmfile.htm)
- .html文件(为了这个例子,我会引用其中之一:htmlfile.html)
- http://domain.com (obviously fictitious name...) hosted on a server running Apache with mod_rewrite enabled
- folder named "foo": (located at http://domain.com/foo/ and in which I want to put my .htaccess file) containing only 3 types of files .php, .htm, .html
- .php files (for the sake of the example I will refer to one of them: phpfile.php)
- .htm files (for the sake of the example I will refer to one of them: htmfile.htm)
- .html files (for the sake of the example I will refer to one of them: htmlfile.html)
下面是什么,我想实现的:
Here is what I am trying to achieve:
- 当进入 http://domain.com/foo/phpfile.php 或<一HREF =http://domain.com/foo/htmfile.htm相对=nofollow> http://domain.com/foo/htmfile.htm 或 http://domain.com/foo/htmlfile.html 在浏览器的地址栏中打回车:
- 在我重定向和301至 http://domain.com/foo/phpfile 或< A HREF =http://domain.com/foo/htmfile相对=nofollow> http://domain.com/foo/htmfile 或的 http://domain.com/foo/htmlfile (根据我所选择的文件),也就是说,那些后者现在显示的网址地址栏
- when entering http://domain.com/foo/phpfile.php or http://domain.com/foo/htmfile.htm or http://domain.com/foo/htmlfile.html in my browser's address bar and hitting "Enter":
- I get redirected with a 301 to http://domain.com/foo/phpfile or http://domain.com/foo/htmfile or http://domain.com/foo/htmlfile (depending on the file I've chosen), that is to say that those latters are the URLs now displayed in the address bar
- 在我没有被重定向,在地址栏没有任何变化,而是在服务器只是提供了我phpfile.php或htmfile.htm或htmlfile.html,具体取决于我要求
我一直在努力在这一点,SOFAR我来到这个内容我的.htaccess文件(位于foo的文件夹中),这是不幸的是唯一的工作在过去的两起案件,其中我感兴趣的(即服务phpfile.php当我要求phpfile,服务htmfile.htm当我要求htmfile或作htmlfile.html当我要求HTMLFILE),并且被忽略301重定向:
I have been trying hard on this, and sofar I've came with this content for my .htaccess file (located in the "foo" folder), which is unfortunately only working in the last of the two cases, in which I am interested (ie serving "phpfile.php" when I request "phpfile", serving "htmfile.htm" when I request "htmfile" or serving "htmlfile.html" when I request "htmlfile"), and which is ignoring the 301 redirections:
Options +FollowSymLinks RewriteEngine on RewriteBase /foo # Redirect permanently the requests for existing .php files # to extensionless files (non present on the server) # so that phpfile.php gets redirected to phpfile RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} \.php$ RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule (.*)\.php$ $1 [R=301,NC] # Redirect permanently the requests for existing .htm(l) files # to extensionless files (non present on the server) # so that htmfile.htm gets redirected to htmfile # so that htmlfile.html gets redirected to htmlfile RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} \.html?$ RewriteCond %{REQUEST_FILENAME}\.html? -f RewriteRule (.*)\.html?$ $1 [R=301,NC] # Matching requests for non existing extensionless files # with their existing equivalent on the server # so that domain.com/foo/phpfile will display # the contents of domain.com/foo/phpfile.php, RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule (.*)$ $1.php [L] # so that domain.com/foo/htmlfile will display # the contents of domain.com/foo/htmlfile.html, RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule (.*)$ $1.html [L] # so that domain.com/foo/htmfile will display # the contents of domain.com/foo/htmfile.htm, RewriteCond %{REQUEST_FILENAME}\.htm -f RewriteRule (.*)$ $1.htm [L]
感谢您事先的任何帮助/建议。
Thank you in advance for any help/ advice.
推荐答案
有逻辑缺陷的前两个规则,因为它是一个存在的PHP或HTML文件。该URI检查也是生效的重写规则模式的复制和!˚F暗示!-d。您还可以折叠这些成一个单一的规则:
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]
最后两个都OK,但我调换顺序,如果HTML请求是比较常见的比PHP
The last two are OK, but I'd swap the order if html requests are more common than php
选项+多视图
实现了被称为的内容协商,并在这样的Apache调用一个子查询来解析文件名的根名称。其中之一是它做的事情是扫描目录已知filename.extension组合,所以在这种情况下,如果xxx.php
存在,你的要求是XXX
那么它将替代的 xxx.php ,然后做了一个内部重定向,然后使你的第一个规则火,取出的.php 扩展这会导致你看到的错误。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 ifxxx.php
exists and your request is forxxx
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.所以(我),你需要禁用多视图,以及(ii)同上子查询; (三)检测和prevent重试循环。这是一种解决方案,这将做你想要的:
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]
这篇关于通过隐藏的.php和.htm(L)扩展和重定向到无扩展名的URL强制的URL重写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!