导言
每一个网页开发者都想让自己的网站拥有一个或狂拽酷炫,或标新立异,或清新文艺的URL地址。就像每一对父母即使费尽心机、绞尽脑汁,也要给自己的孩子起一个有个性的好名字一样。一个好的网站地址不仅能够让来访用户在还没进入网站之前就知晓网站的主要内容(比如,知名在线编程教学网站www.codecademy.com,只看这个URL就知道是与编程相关),更重要的是,一个简洁直观且达意的URL将大大的利于搜索引擎优化(SEO, Search Engine Optimization),让搜索引擎能够更好的识别网站的信息与内容,从而提升网站在搜索引擎出现的位置以获取更多的访问量(谷歌君看完这句话给我点了一个赞,而度娘没有任何反应。于是我问她:“女神,我不知道你是怎么看待SEO这件事的,但为什么你们家的搜索结果总是给人一种钦定的感觉呢。。。” )。今天,我们就来探讨一下如何“PS”网站的URL,让它们看起来更“美丽动人”。
URL重写
1. 什么是URL重写?(URL Rewriting)
URL重写就是利用服务器端的URL重写模块(URL Rewriting Module)以及基于Perl语言的正则表达式,将真实的URL隐藏起来,跳转到另外指定的URL。
比如,我们拥有一家网上水果商店,它的网址是:
http://www.freshfruits.com/
当一位用户在该网站选择了苹果这个类别时,URL变为:
http://www.freshfruits.com/get_fruits_by_name.php?fruit_name=apple
可是我们并不想也不需要让用户看见这个冗长“丑陋”的URL出现在浏览器地址栏,我们想给用户看的是这样的一个简单明了“颜值高”的URL:
http://www.freshfruits.com/apple
利用URL重写模块,我们就可以实现这个目标。换句话说,当用户看到“www.freshfruits.com/apple”这个网址时,事实上浏览器渲染的真实页面是“www.freshfruits.com/get\_fruits\_by\_name.php?fruit_name=apple”。这样,就完成了对用户隐藏真实的URL,让另外一个更“好看”的URL显示在用户的浏览器地址栏的任务。
对于最常用的两种Web服务器Apache和IIS来说,Apache本身就内置了URL重写模块,而IIS则需要使用相关插件来实现。本文的所有代码和实例都基于Apache服务器。
2. 正则表达式
没有正则表达式,就没有URL重写。在我的印象里,正则表达式就跟它的名字一样,古怪,神秘,但听起来又逼格十足。它常常出没于需要对字符进行匹配查找替换等情境中,强大到超乎想象。如果想要深入的学习它,就自行上网搜索一下吧,精彩的教程多到令人目不暇接。如果不感兴趣也没关系,只要记住下面这些基本的元字符就足以Hold住大部分的URL重写了。
. (匹配任意单个字符)
* (匹配前面的子表达式0次或多次,即任意次)
+ (匹配前面的子表达式至少1次)
^ (匹配输入字符串的开始位置)
{} (限定匹配次数)
? (非贪婪匹配,即匹配前面的子表达式0次或1次)
! (相当于逻辑"非")
$ (匹配输入字符串的结束位置)
[] (匹配所包含的任意字符)
() (将括号间的表达式定义为"组")
| (逻辑"或")
\\ (转义字符)
3. URL重写的基本步骤
先举一个简单的例子:
我们要把这个URL隐藏起来:
http://www.freshfruits.com/apple_product_info.php
而我们想要浏览器地址栏显示的是这个URL:
http://www.freshfruits.com/apple/
首先,我们需要到Web服务器的根目录下新建一个“.htaccess”文本文件(与apple\_product\_info.php在同一级目录,这里需要注意,新建的文件名称就叫“.htaccess”,句点前不要加任何前缀)。“.htaccess”是一个简单的服务器配置文件。如果在根目录下已经有了一个“.htaccess”文件(通常为隐藏文件),我们只需要打开修改里面的内容就好了。
接下来,用任意一种文本文档编辑器打开.htaccess文件,在里面添加下面这两行代码:
RewriteEngine On # 打开URL重写引擎
RewriteRule ^apple/?$ apple_product_info.php [NC,L] # 创建重写规则,在这里我们让服务器把满足匹配^apple/?$模式的URL请求转向apple_product_info.php。想知道[NC, L]是什么,接着往下看。。。
利用最基本的正则表达式 "^apple/?$"及重写规则,我们就完成了对URL的"易容"。
4. 立"Flag"要慎重
你没有看错,我们就是要立Flag。Flag是URL重写里很重要的一个概念,是它告诉Apache服务器该怎样去理解和处理重写规则。上面的例子中,[NC, L]里的NC和L就是两个Flag。那么,就让我们通过下面的总结来看看这些Flag到底是什么意思吧。
C (chained with next rule) 关联下一个规则
CO = cookie (set specified cookie) 设置指定的cookie
E=var:value (set environment variable var to value) 设置环境变量
F (forbidden - sends a 403 header to the user) 禁用URL并返回403HTTP状态码
G (gone - no longer exists) 强制URL为gone并返回410HTTP状态码
L (last - stop processing rules) 指定当前规则为最后执行的一条规则,之后的规则将被忽略
N (next - continue processing rules) 从第一条规则重新开始重写
NC (case insensitive) 不区分大小写
NE (do not escape special URL characters in output) 不再输出特殊字符,如转义字符
NS (ignore this rule if the request is a subrequest) 忽略子请求
P (proxy - i.e., apache should grab the remote content specified in the substitution section and return it) 强制使用代理
PT (pass through - use when processing URLs with additional handlers, e.g., mod_alias) 传递处理
R (temporary redirect to new URL) 暂时重定向
R=301 (permanent redirect to new URL) 永久重定向
QSA (append query string from request to substituted URL) 追加请求字符串
S=x (skip next x rules) 跳过接下来的x条规则
T=mime-type (force specified mime type) 强制MIME类型
让我们对照着这份Flag总结再次回到上面那个例子中。[NC, L]就是告诉服务器,不需要区分大小写,然后忽略其他的规则。所以,即使你输入了大写的地址,比如"www.freshfruits.com/Apple/",服务器也能够返回正确的页面信息。
5. 不只是为了好看
可能你会问,我们为什么要对URL进行重写呢,难道只是因为好看?我的回答是,是的,就是为了好看 。好吧,我错了。各位看官别走,我哪有这么肤浅。。。
对于简单的单页网页应用(某些小的Landing Page)来说,没有那些复杂的功能,一个固定的静态URL就可以代表一切。而从那些稍微复杂的网站开始,比如有多页面需要页面间的跳转,有用户信息的登录登出,有网页内表格的提交等等,就必须使用动态URL来实现这些功能。所以,我们看到的URL就变成了这样:
http://www.fruits.com/users.php?user_name=主席&user_gender=男&user_birthday=1926
然而,这样的URL真的好嘛,把用户的名字性别生日等个人信息彻底暴露,甚至还可能会泄露用户的个人密码。而这个时候,利用URL重写规则,我们不仅仅能让URL变得好看,更重要的是可以使用户的信息得到更好的保护。
这才是URL重写的主要目的:动态URL的伪静态化。
总结
利用重写规则我们可以做很多复杂且高效的URL重写,譬如,我们还可以添加Rewrite Conditions(重写条件)来控制允许URL重写的条件。限于篇幅(其实是我不想写了,规则太多写不下去了。。。逃。。。),本文只展示了一个极其简单到令人发指想打作者的重写实例。然而,窥一斑而知全豹。在遇到自己开发的网页需要对URL进行修饰的时候,我们便会想到利用服务器的URL重写模块,并且深入学习强大的URL重写规则,从而获得我们需要的重写效果。