Sein Link(er) Gang
这是一个令人恐惧的例子,说明了链接历史如何影响了Martin Raja和Arlen Walker,以及他们(链接)随后是如何被无情地打击的。
标题(原文Dead Link Walking)是对电影“Dead Men Walking”的引用——在德语中不甚恰当的翻译为“Sein letzter Gang”。好吧,我已经尽力翻译了,但这个玩笑可能并不那么好笑。抱歉。
"嘿!这个链接已经不能用了!"
这绝对不是在顺利升级后希望听到的。在任何情况下都不是。而这个案例的情况当然远非理想。地址栏中的链接看起来完全扭曲,几乎无法识别。
这个链接是从哪里来的?好吧,太棒了.. 这是一个完全过时的格式中的链接,它包含一个"task=view"指令,指示Joomla!显示一个页面。旧。非常旧,极其旧。
但这还不是全部,还有更糟糕的事情。这个可爱的链接仍然被发送在电子邮件中,甚至今天还在发送;当然,这个链接是有效的,至少一年。这给了我们两种选择:调整电子邮件并设法让这个旧链接仍然有效——或者调整邮件并等待一年,直到Joomla! 1.5迁移。显然,第二种选择立即被排除。
那么,应该怎么做呢?首先,我们认为这是一个Apache的mod_rewrite模块的简单任务,所以我们从那里开始。然而,最初的几次尝试都以失败告终,Google叔叔也没有提供合理的建议——显然,没有人曾经成功做到过这样的事情。
忠实的友人建议我们为这种情况编写一个自己的路由器插件,但如今,我们被这种雄心所驱使;我们想要让Apache按照我们的意愿行事。我们不时地敲打这个问题,每一次尝试都让我们离解决方案更近一步——但解决方案就是找不到。最终,是我的合著者Martin找到了缺失的拼图碎片。
我们最初的想法是写一个完整的正则表达式集合,用它们将每个“view=article”替换为“task=view”,但经过几次失败的实验后,我们放弃了这个想法,简化了任务:实际上没有必要移除“task”参数,Joomla!最终会简单地忽略它。我们唯一需要做的是添加“view”参数。然而,这却激起了Apache无限循环的欲望。尽管这让我们在错误查找上花费了大量时间,但我们最终找到了这个谜题的解决方案。
解决方案由三行mod_rewrite命令组成。对于类似的情况,此代码推荐使用;它解决了我们的问题(我们只遇到了链接到文章的问题)和虽然我们的代码对于解决其他情况不一定适用,但我们的解决方案可以作为指导。
为了完全理解我们做了什么,我们需要简要了解Apache的mod_rewrite和正则表达式。关于这两个主题有大量优秀的介绍,因此这里只提及两个链接。一个是Apache的mod_rewrite文档,另一个是正则表达式的介绍。(两者都是英文)
了解了这些后,我们戴上安全帽和护目镜,仔细查看Rewrite代码
RewriteCond %{QUERY_STRING} ^(.*)task=view(.*)$
RewriteCond指令定义了执行以下行所需的条件。每个规则都必须在评估时返回“True”,然后才会执行下一个RewriteRule。上面的行会在URL中某处出现“task=view”时返回“True”。(^表示字符串的开始,$表示字符串的结束,“.”表示任意字符,“*”表示重复任意次数,因此这个表达式检查整个字符串。)
RewriteCond %{QUERY_STRING} !(view=article)
这一行是解决问题的关键。Apache喜欢循环!如果它做了修改,就会重复执行。当我们尝试向字符串中添加新表达式时,这一点突然变得清楚。如果没有这一行,Apache会陷入无限循环并阻塞服务器。或者,如果它没有意识到自己倾向于循环,它就会拒绝执行可能导致循环的Rewrite。这种特殊特性在我们早期的尝试中多次给我们带来麻烦,直到Martin最终发现了这里发生的事情。这一行是防止这种行为的一种保护措施;如果字符串中存在“view=article”参数(“!”表示非),则该指令的结果为“False”,我们将在这一点上离开规则集——并因此跳出循环。
RewriteRule ^.*$ /$0?%1view=article%2 [R=301,L]
现在我们进入正题。行首的“^.*$”部分选择整个URI,就像它到来时一样。行尾部分编写了新的重写请求。$0部分接受第一个规则部分选择的字符串,并在其后加上“/”,这样我们就可以得到URI的“/index.php”。
表达式 %1 和 %2 被称为回溯引用,它们指向第一个 RewriteCond 分解的 URI (.*)中的两个部分,包围着“task=view”——现在在新编写的请求中包围着“view=article”。
行末括号中的两个参数(“R=301”和“L”)表示:执行301重定向,并且这是该规则的最后一个指令。
所有这些将过时的请求转化为一个由现代 Joomla!理解的显示文章指令——这正是我们想要达到的效果。
虽然这个重写规则适用于我们的特殊情况,但显然不能捕获所有可能的 Joomla!1.0 请求。但是,即使对于其他特殊案例可能也不够用,这篇文章仍然可以作为如何通过重写规则应对此类问题的指南。
本文最初由 Arlen Walker 和 Martin Raja 撰写,并发表在 2013 年 5 月的 Joomla!社区杂志上。
发表在 Joomla!社区杂志上的一些文章代表作者对特定主题的个人观点或经验,可能不代表 Joomla!项目的官方立场。
通过接受,您将访问 https://magazine.joomla.net.cn/ 外部的第三方服务。
评论