Apache mod_rewrite
你需要的是mod_rewrite,
描述: 提供了一个基于规则的重写引擎,可以实时重写请求的URL。
一般来说,mod_rewrite
通过匹配指定的正则表达式来处理请求的文档,然后在Apache进程内部(内部重写)或客户端浏览器中(外部重写)执行URL重写。这些重写可以简单地将example.com/foo
内部转换为对example.com/foo/bar
的请求。
Apache文档包含一个mod_rewrite
指南,我认为其中涵盖了您想要做的一些事情。详细的mod_rewrite指南。
强制使用www
子域名
我希望它在每个URL之前都强制使用"www",所以不是domain.example
而是www.domain.example/page
重写指南包含了这方面的说明,在规范主机名示例下。
删除尾随斜杠(第一部分)
我想要删除所有页面的尾随斜杠
我不确定为什么您要这样做,因为重写指南包括相反的示例,即始终包含尾随斜杠。文档建议删除尾随斜杠可能会导致问题:
尾随斜杠问题
描述:
每个网站管理员都能唱出关于URL引用目录时尾随斜杠的问题。如果缺少它们,服务器就会抛出一个错误,因为如果你说/~quux/foo
而不是/~quux/foo/
,那么服务器将搜索名为foo的文件。由于此文件是目录,它会抱怨。实际上,在大多数情况下,它会尝试自行修复,但有时需要您模拟此机制。例如,在您完成了许多复杂的URL重写到CGI脚本等之后。
也许您可以解释一下为什么您想始终删除尾随斜杠?
删除.php
扩展名
我需要它删除.php
我能想到的最接近实现此目的的方法是将每个请求文档内部重写为 .php 扩展名,即
example.com/somepage
实际上被处理成了对
example.com/somepage.php
的请求。请注意,这样做需要确保每个somepage实际上存在于文件系统上作为 somepage.php。
通过正确组合正则表达式,这应该在一定程度上是可行的。但是,我可以预见到一些可能出现的问题,例如索引页面未能正确请求和无法正确匹配目录。
例如,这将正确地将
example.com/test
重写为对
example.com/test.php
的请求:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
但是,由于没有example.com/.php
,将导致example.com
无法加载。
我猜测,如果您删除所有尾随斜杠,则从对父目录中文件名的请求中选择对目录索引的请求将变得几乎不可能。您如何确定对目录"foobar"的请求:
example.com/foobar
从一个请求名为foobar的文件中(实际上是foobar.php文件)
example.com/foobar
如果您使用
RewriteBase
指令,可能是可行的。但如果您这样做,那么这个问题会变得更加复杂,因为您需要使用
RewriteCond
指令来进行文件系统级别的检查,以确定请求是否映射到目录或文件。
话虽如此,如果您放弃删除所有尾随斜杠的要求,而是强制添加尾随斜杠,“无 .php 扩展名”问题就会变得更加合理一些。
RewriteEngine on
RewriteCond %{REQUEST_URI} !\.php$ [NC]
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
这还不完美--每个文件请求仍然在内部附加了.php。请求“hi.txt”将在您的错误日志中记录如下:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
但是还有另一种选择,可以像这样设置
DefaultType
和
DirectoryIndex
指令:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
2013-11-14更新 - 修正了上面代码片段中nicorellius的观察结果
现在可以成功请求hi.txt(以及其他任何文件),对于example.com/test
的请求将返回处理过的test.php版本,index.php文件也将再次正常工作。
我必须为这个解决方案所给予的信誉致谢,因为我通过谷歌搜索php no extension apache找到了Michael J. Radwins Blog。
删除末尾斜杠
一些搜索关于apache remove trailing slashes
的结果带我来到了一些搜索引擎优化页面。显然,某些内容管理系统(本例中为Drupal)会使内容在URL中有或没有末尾斜杠可用,在SEO领域中这会导致您的网站遭受重复内容惩罚。来源
解决方案似乎非常简单,使用mod_rewrite
,我们在请求资源以/
结束的条件下进行重写,并通过发送301永久重定向
HTTP头来重写URL。
这是他的示例,假设您的域名为blamcast.net,并允许请求以www.
作为前缀。
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
现在我们有所进展了。让我们把它们放在一起,看看它是什么样子。
强制使用www.
,不使用.php
,以及不要使用尾随斜杠
这假设域名为foobar.example
,并且它正在标准端口80上运行。
DefaultType application/x-httpd-php
DirectoryIndex index index.html
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/?(.*) http://www.foobar.example/$1 [L,R,NE]
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
'R'标志在RewriteRule
指令部分中有描述。摘录:
redirect|R [=code]
(强制重定向)前缀替换为http://thishost[:thisport]/
(使新URL成为URI),以强制进行外部重定向。如果未提供代码,则将返回HTTP响应302(暂时移动)。
最终说明
我无法成功地使斜杠删除工作。重定向最终导致我无限重定向循环。在仔细阅读原始解决方案后,我认为上面的示例适用于他们的Drupal安装方式。他特别提到:
在启用了干净的URL的普通Drupal网站上,这两个地址基本上是可以互换的
关于以斜杠结尾和不带斜杠的URL。此外,
Drupal使用一个名为.htaccess
的文件告诉您的Web服务器如何处理URL。这是启用Drupal的干净URL魔术的同一文件。通过在.htaccess
文件开头添加一个简单的重定向命令,您可以强制服务器自动删除任何尾随斜杠。