Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

mod_rewrite的特殊字符问题

  对于普通的页面mod_rewrite还是很好用的,但是遇上一些特殊的页面就不搞定了。最典型的就是搜索页,如果使用GET方法传递搜索字符串就很有可能在URL中包含特殊字符,这时用mod_rewrite处理搜索字符串就会出问题。因为mod_rewrite有一套诡异的转意模式。
  我们需要解决一个最基本的问题,当用户访问“/search/word/”的时候需要把word传给某个程序处理,这里的例子就用“search.php”吧。它就一行代码 echo $_GET['s'];   最简单的做法是直接匹配参数传递给程序,一条RewriteRule规则搞定 RewriteRule ^search/(.+)/$ /search.php?s=$1
  正常的查询字符串是没问题,但是如果带有特殊字符就会解析错误。为什么会错误呢?这原因还不太单纯。首先是因为斜杠和反斜杠都是slashes字符,对于slashes字符在Apache中默认是不允许URL转意的,需要在配置中手动开启。也就是到httpd.conf中在站点设置中天添加“AllowEncodedSlashes On”
<VirtualHost *:80>
    AllowEncodedSlashes On
    DocumentRoot "网站主目录"
</VirtualHost>
  记得添加完成后需要重启Apache。但是这还没完,允许slashes转意只是意味着客户端输入的URL能够正常的传到mod_rewrite中处理。但是在mod_rewrite中,RewriteRule这个语法本身是不识别这样特殊的URL的。所以我们依然无法直接使用RewriteRule来处理这个URL。这时候可以使用RewriteCond语法,它比RewriteRule更深一个层次,可以访问到这个特殊的URL。从客户端传过来的URL是储存在服务器变量中的REQUEST_URI中,我们需要在RewriteCond中匹配REQUEST_URI中需要的字符串,然后再传入RewriteRule。
RewriteCond %{REQUEST_URI} ^/search/(.+)/$
RewriteRule ^ /search.php?s=%1

  这样,我们就可以匹配到slashes了,但是问题并没有完全解决。因为除了slashes还有其它特殊字符,比如“%23”是“#”字符,它依然无法正常传递。其实通过上面的步骤已经对字符正常解析了,现在的问题出在“/search.php?s=%1”上。当客户端把URL传递给Apache时就已经解析了转意字符,可是现在我们把已经解析了的转意字符直接传到“/search.php?s=%1”这个URL上当然会出问题。所以此时我们需要对字符重新转意,然后再传递给search.php。其实这个步骤很简单,mob_rewrite有提供这个功能,只要在RewriteRule之后添加“B flag”即可。 RewriteCond %{REQUEST_URI} ^/search/(.+)/$
RewriteRule ^ /search.php?s=%1 [B]

网名:
54.226.58.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^