HostMonster:Redirects错误
出自美国主机知识库
问题:
从www.yourdomain.com/default.html 或者 index.html到http://www.yourdomain.com/index.php?act=whatever的重新定向将会定向到http://www.yourdomain.com/index.php%3fact=whatever。
换句话说,为什么地址栏里的"?"被替换成了"%3f"(或别的)?
答案:
这可说来话长了…………
.htaccess hacker最强大的一个能力之一就是重写URLs。这允许我们对我们的链接做一些有力的操作,有用的如,把长URLs变成短小简练的URLs,把动态链接URLs ?generated=page&变成友好的单一的链接,重新定向丢失页面,阻止盗链,自动语言翻译,更多更多。
不必怀疑,mod_rewrite很复杂,这不是一个一口就能吃下去的技术快餐,更不是一个周末速成班。我看到了一些人使用mod_rewrite做出了一些成果,但是荣誉的帽子不断的加到这来自地狱的操作者和魔术一般的模块的作者Ralf S. Engelschall的头上,我承认对我对它还是十分迷惑的。
这种上一分钟规则可以运作而下一分钟就失效的方式,以及浏览器和其他网络缓存如何实现与规则相互作用和测试规则,是令人十分沮丧和发狂的。当我感觉到需要把思想专注于表面之外的东西时,我被mod_write弄得一团糟糕。
在这一切之后,开始有效果了。在我不打算参加周末速成班的时候,我自己掌握了一些诀窍,开始在网络服务器和网站上浪费时间…
这里的计划是介绍一些灵活的东西,例如,证明很有用的,适用于多种服务器的建立的,在我的LAN到处都是apache。我不断遇到老的.htaccess文件,用以前的重写方法实验。仍然有效的就放入列表,遇到失败的就心情沉闷。令我惊奇的是经历了这些之后,我可以准确地看出原因。
这里没有任何东西是我的发明。甚至我指出的bit都是已经写好了的,我只是不能理解这些文档,或者说找不到他们。有些时候,从另一个不同的角度看同一个事情会变得很不同,所以这种URL重写带来的挫败的刺痛对我们是有一些用处的。当然我是为自己写的,但我也获得了一些荣誉。
# time to get dynamic, see..
rewriterule ^(.*).htm $1.php
开始rewriting:
不管你什么时候使用mod_rewrite(apache里最有魔力的地方),你需要在重写之前做如下:
每一个.htaccess文件只需要做一次:
Options +FollowSymlinks
RewriteEngine on
+FollowSymLinks是规则运作所必需的,这是重写引擎的安全需要。普通情况下根目录已经开启了你并不需要额外增加,但这样做也无妨,为了以防万一,我会在该页的所有例子里插入 。
下一行就是简单地开启该文件夹的重写引擎。如果你的.htaccess文件有这个指令,那么理论上你的整个站点都开启了重写引擎。但是明智之举是在写重新定向之前加入该行。
注意:尽管本页的一些指令看起来像2行,在你的.htaccess文件里必须是1行。
简单rewriting:
简单出发,Apache扫描所有的外来的URL请求,寻找匹配的.htaccess文件,并把那些匹配的URLs重写到我们指定的像. Something一样的东西里。
任何到一个.htm的请求都会被发送到另一个.php。
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.*).htm $1.php [nc]
可以方便任何人将一个静态站点.htm(同样可以说.html,.htm(*))升级成动态.php页面。指向老页面的请求将会被冲重新定向到我们的新的urls。没人注意到一件事,访问者和搜索引擎可以通过任何一种途径访问你的内容。作为一个额外的好处,这允许我们轻松地将php代码及其包括的html结构分割成2个独立的文件,真是一个好主意。并且编辑和升级将变的轻而易举。最后的[nc]意思是“不需要大写”,或者“大小写不敏感”。
人们可以连接到任何.htm和.php站点,但是他们的浏览器总是显示.php站点,就像.htm不存在一样。我很迷惑。
这确实有一点小把戏。人们的浏览器地址栏里仍然会有.htm,仍然会收藏你的旧的.htm URLs。搜索引擎也一样,会继续标记你的的.htm链接。有些甚至争论2个地址是一样的内容会遭到搜索引擎的惩罚。也许这没有困扰到你,如果有的话,mod_rewrite会魔术一样的解决这个问题。
这会做一个“真实的”http重新定向:
Options +FollowSymlinks
rewriteengine on
rewriterule ^(.+).htm$ http://yourdomain.org/$1.php [r=301,nc]
这次我们指示mod_rewrite发送一个合适的固定步骤地HTTP重新定向,“301”。现在重新定向不再是黑箱操作,用户的浏览器被重新定向到新的URL,地址栏里将会出现.php地址,搜索引擎和其他会将他们的链接自动更新到新的.php版本,每个人都是赢家,你也可以从容进行升级。
不那么简单的rewriting
你可能已经注意到,上面的例子使用规则的表达式匹配变量。也就是意味着要匹配(.+)里的部分,并且用它来建造新的URL里的"$1"。换句话说 ,(.+) = $1。你可能有多个(.+)部分,那么对每一个mod_rewrite都会自动为你的目标URL匹配类似$1, $2, $3的东西。
更复杂的rewrite规则:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^files/(.+)/(.+).zip download.php?section=$1&file=$2 [nc]
允许你呈现这样的链接:
http://mysite/files/games/hoopy.zip
背地里则转向了
http://mysite/download.php?section=games&file=hoopy
一些脚本可以做到。你看到了,很多搜索引擎并不只是简单地采用我们的?generated=这样的链接,所以如果你创建生成页面,这将会十分有用。但是,这些搜索引擎无法处理这类链接,他们不会说话,我们只能问自己。我们真的想被这些不会说话的搜索引擎列出吗?Google可以处理相当一些你的URL里的参数而不会有任何困难,一个真实存在的搜索引擎msn-bot为了获得某个页面永远不会停下来,再一次再一次地重复。
我个人感觉搜索引擎需要努力以紧跟现代网络技术,换句话说,我们不需要为了搜索引擎而降低技术。但那只是我的选择。很多用户更倾向于/files/games/hoopy.zip而不是/download.php?section=games&file=hoopy。2种我都不介意。就像最近有人向我指出的一样,提供标准的路径如/standard/paths意味着人们在输入URLs的时候不需要太繁琐。所以像下面这样的甚至更复杂的rewrite规则:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^blog/([0-9]+)-([a-z]+) http://yourdomain.org/blog/index.php?archive=$1-$2 [nc]
将会是一个很好的窍门,允许他通过在浏览器输入:
http://yourdomain.org/blog/2003-nov
访问我的blog的文档,而这个输入将会在服务器端自动转变为:
http://yourdomain.org/blog/index.php?archive=2003-nov
这样你的blog域名就能识别了。很简单就能想到,只需要一点想象,或对posix规则地表达式有基本理解,你就可以实现一些相当漂亮的URL操作。
缩短URLs:
Mod_rewrite的一个常见用法是缩短URLs。短的URLs更容易记忆,当然也更容易输入。例如:
小心规则地表达式:
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^grab(.*) /public/files/download/download.php$1
这条规则将会把该用户的URL:
http://mysite/grab?file=my.zip
在服务器端转化为:
http://mysite/public/files/download/download.php?file=my.zip
这是我我在其他东西中为我的distro机器使用的小窍门。所有人都爱短小的URLs,你也一样。使用这个技术,你可以把/public/files/download/移动到你的站点的任何地方,所有的老的链接仍然有效。只要改变你的.htaccess文件中的一行来反映新的位置。意味着即使是站点深处的东西,仍然可以有像这样很酷的地址: http://yourdomain.org/img/hotlink.png [nc]
也许你看到最后一行变成了2行,但其实是1行(本页的指令都是这样)。
让我们稍微看一下是怎么做的。
像通常一样,我们从启动rewrite引擎开始:
第一行RewriteCond允许直接请求(不是来自其他页面-空链接)。下一行的意思是,如果你的浏览器确实发送了一个链接的开始部分,但是“你的域名“却没有出现在域名部分,那么就重写该请求。
非常重要的RewriteRule最后行指示mod_rewrite重写所有匹配的需求gifs,jpegs或者pngs图片的请求(不包含“你的域名”的链接),指向一个可选择的图像.mine,该图像表达一个意思,“请不要盗链”。这里你可以看到他在运作。有很多办法可以写这个规则。Google一下“hot-link protection(防盗链)”,你能得到一大堆结果。简单的是最好的。你可以发送一条小信息,或者把他们指向一些不好的脚本,或者别的。
httpd.conf
记住,如果你把这些规则放入了服务器的配置文件(通常是httpd.conf)而不是放入一个.htaccess文件,那就必须在RewriteRule的开始行使用^/... ... i而不是^... ...。
换句话说,加个斜线。
继承:
如果你在站点的子目录里创建规则,那么必须读一读下面的。
你将会记得上一级目录里的规则如何应用到该目录里的所有目录中去。我们称为“继承性”。通常是有效的。但是如果你在子目录里创建了其他规则,那么就可以有效地除去由继承性应用到该文件夹的规则。不是所有规则,仅仅是应用到子文件夹的那些。一个小的例子:
假设我在main /.htaccess写了一个规则,这个规则将对文件ending.htm的请求重新定向到一个等价的therr.php文件,就像本页上面的一个例子。现在,如果我因为任何别的原因需要向/osx/.htaccess文件添加rewrite规则,.htm >> .php的重新定向在/osx/子文件夹就不再有效。我需要再插入他,但是相当的不同。
在我的.重要的.htaccess文件中,全站工作良好:
# main (top-level) .htaccess file..
# requests to file.htm goto file.php
Options +FollowSymlinks
rewriteengine on
rewriterule ^(.*).htm$ http://yourdomain.org/$1.php [r=301,nc]
这是我最新的/osx/.htaccess文件,重新插入了.htm >> .php重新定向。
为了使其在子文件夹里工作,我需要重新插入规则。
# /osx/.htaccess file..
Options +FollowSymlinks
rewriteengine on
rewriterule some rule that I need here
rewriterule some other rule I need here
rewriterule ^(.*).htm$ http://yourdomain.org/osx/$1.php [r=301,nc]
发现子文件夹里规则的不同之处,用红色突出。你必须把当前路径添加到新的规则。现在它又工作了。如果你记住了这点,就可以到处复制rewrite规则了。
总结
简短地说,mod_rewrite允许你把浏览器从一个地方送到另外一个地方。你可以创建不是简单地以被请求URL为基础的规则,同样能够以IP地址,浏览器代理(例如将旧的浏览器发送到不同页面),甚至是时间为基础。可能性实际上是无限的。
Mod_rewrite语法的来龙去脉是一个比本文长的多的文档的主题。如果你想试验更多的高级rewriting规则,我建议你看apache文档。如果你使用*nix操作系统(事实上是,不管什么操作系统只要安装了apache),你的电脑上就会有一本apache手册的复印件,这是极好的mod_rewrite教程。记得看URL Rewriting Engine注意事项里的有趣的句法。
http://www.ilovejackdaniels.com/apache/mod_rewrite-cheat-sheet/
http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html
http://httpd.apache.org/docs/1.3/misc/rewriteguide.html
http://forum.modrewrite.com/