Apache URL重写规则

1、简介

  Apached的重写功能,即凡mod_rewrite模块功能,它是apache的一个模块。它的法力十分强劲,可以操作URL中之享有有。

  因此我们尽管可以改写url,给用户提供一个简介大方的url,当用户访问时可透过mod_rewrite模块功能转移为真的资源路。通过mod_rewrite能落实的效力还有多,例如隐藏真实地址、实现URL跳转、域名跳转、防盗链、限制访问资源类型等等。

2、工作流程

  mod_rewrite模块于运行时会见动有限单Hook程序。

  第一独凡是自URL到文件称转移的Hook。当起看到达Apache服务器的经常,服务器会确认相应主机(或虚拟主机),这时mod_rewrite模块就开始工作,它以见面先拍卖服务器全局中mod_rewrite模块所提供的指令,然后因用户提供的通令进行变更写。

  第二只是修正URL的Hook。在此路mod_rewrite模块会处理非全局的安装。例如,目录中的.htaccess文件中之设置。但是这都好URL的翻译(由URL转换为文件称),因此是无法在不好对目录级别之URL进行改动写操作,但是moe_rewrite模块会将曾翻的URL再次转移为URL的状态,继续拓展目录级别的URL改写。(mod_rewrite模块将会下读后呼吁阶段的回叫函数重新开一个请求的循环处理)

Rewirte模块规则集的拍卖

  当mod_rewrite于当下片独API阶段中初露执行时,它见面读取配置结构中安排好之
(或者是当劳务启动时植之劳动器级的,或者是在遍历目录集到之目录级的)规则集,然后,启动URL重写引擎来处理(带有一个或者多单标准的)规则集。无论是服务器级的要么目录级的规则集,都是由同一个URL重写引擎处理,只是最终结出处理不同而已。

  规则集中规则的依次是深重要之,因为重写引擎是以同种植特别之相继处理的:逐个遍历每个规则(RewriteRule指令),如果出现一个匹原则的规则,则恐回头遍历已有些规则条件(RewriteCond指令)。由于历史之案由,条件规则是放的,所以决定流程略发冗长,细节展现图-1。

图片 1

  可见,URL首先和每个规则之Pattern匹配,如果匹配失败,mod_rewrite将随即停下这个规则的拍卖,继而处理下一个平整。如果配合成功,mod_rewrite将搜对应的规则条件,如果一个尺度还未曾,则略地用Substitution构造之新值来替换URL,然后继续处理其他规则;但是要基准是,则开一个里头循环按该列有底逐一依次个处理。对规则条件的拍卖有所不同:URL并无跟模式展开匹配,而是首先通过扩大变量、反向引用、查找映射表等手续建立一个TestString字符串,然后用其来跟CondPattern匹配。如果配合失败,则遍条件集与相应的平整失败;如果配合成功,则履行下一个规则直到有标准执行完毕。如果具有规则好匹配,则为Substitution替换URL,并且延续处理。(本有引用译者:金步国)

网络图片:

图片 2

 

3、URL重写指令

  最简易的重写指令可以省略到让您无法想像!

  只待简单步就是足以得了。第一运RewriteEngine开启mod_rewrite模块功能;第二由此RewriteRule定义URL重写规则

  1)、URL重写指令套路

1 ---------------------------------------------------------------
2 RewriteEngine on   #开启mod_rewrite模块功能
3 RewriteBase 路径     #基准URL(使用alias设置别名则需使用这个)
4 RewriteCond TestString CondPattern [flags]      #重写条件(可以多个)
5 RewriteRule Pattern Substitution [flags]          #重写规则
6 ----------------------------------------------------------------
7 #4、5行可以可以多个
8 #按顺序一个一个执行RewriteRule([flags不终止情况下])
9 ##以上是常用的指令,还有一些很少见的指令,需要的自己去查资料了解

  2)、RewriteRule Pattern Substitution [flags]

  1、pattern是意为时URL的perl兼容的正则表达式。当前URL是负该规则生效时刻的URL的值。它恐怕跟于呼吁时之URL截然不同,因为事先可能吃其他RewriteRule或者alias指令修改了。

  2、Substitution是当URL与Pattern匹配成功后。用来替代的字符串。

  • 足针对pattern反往引用$N(N=0~9),表示正则表达式中第N个括号受的内容
  • 对最终匹配的RewriteCond反往引用%N(N=0~9),表示最终匹配的RewriteCond第N对括号受的内容
  • 服务器变量%{VARNAME}
  • 映射函数调用${mapname:key|default}
    (通过RewriteMap指令定义映射辅助完成)

  3、[flags],标志符,多单则因此逗号隔开。

标志符(摘抄于网上):

redirect|R [=code] (强制重定向 redirect)

  以 http://thishost\[:thisport\]/(使新的URL成为一个URI)
为前缀的Substitution可以强制性执行一个表重定向。
如果code没有点名,则发一个HTTP响应代码302(临时性移动)。如果需要以于300-400限量外之其它响应代码,只需要以此指定这个数值即可,
另外,还好使下列符号名称有: temp (默认的), permanent, seeother.
用它们可以把规范化的URL反馈给客户端,如, 重写“/~”为
“/u/”,或对/u/user加上斜杠,等等。

留神: 在用这个标记时,必须管该替换字段是一个立竿见影的URL!
否则,它见面指向一个不行的职务! 并且要切记,此标志本身只是针对URL加上
http://thishost\[:thisport\]/的前缀,重写操作仍然会继续。通常,你会希望停止重写操作而立即重定向,则还需要使用’L’标记.

forbidden|F (强制URL为被禁止的 forbidden)

  强制当前URL为为明令禁止的,即,立即上报一个HTTP响应代码403(被取缔的)。使用这标记,可以链接若干RewriteConds以有标准化地打断某些URL。

gone|G(强制URL为都弃之 gone)

  强制当前URL为早已弃之,即,立即上报一个HTTP响应代码410(已弃之)。使用这符号,可以表明页面都为废除而未存了.

proxy|P (强制为代理 proxy)

  此号使替换成分叫内部地强制为代理要,并当即(即,
重写规则处理就暂停)把拍卖移交给代理模块。你要管这替换串是一个得力的(比如大规模的以
http://hostname开头的)能够为Apache代理模块所处理的URI。使用这个标记,可以把某些远程成分映射到本地服务器名称空间,
从而增强了ProxyPass指令的意义。

瞩目: 要使用此效应,代理模块必须编译在Apache服务器遭受。
如果您无克确定,可以检查“httpd -l”的出口中是不是发生mod_proxy.c。
如果有,则mod_rewrite可以应用这效应;如果无,则要启用mod_proxy并再度编译“httpd”程序。

last|L (最后一个规则 last)

  这停止重写操作,并不再以其他重写规则。
它对应于Perl中之last命令或C语言中的break命令。这个符号可以阻止当前既让重复写的URL为该后继的条条框框所重写。
举例,使用它们可以再写根路径的URL(’/’)为实际在的URL, 比如, ‘/e/www/’.

next|N (重新履行 next round)

  重新履行重写操作(从第一独规则更开).
这时还展开处理的URL已经不是本来的URL了,而是经过最终一个复写规则处理的URL。它对应为Perl中之next命令或C语言中的continue命令。
此标记可以还开始重写操作,即, 立即回到循环的脑部。
而是倘若小心,不要打死循环!

chain|C (与下一个条条框框相链接 chained)

  此号使时规则及下一个(其本身还要好跟那个后继规则相链接的,
并可以这么频繁的)规则相链接。 它来如此一个效能:
如果一个规则为匹配,通常会持续处理该后继规则,
即,这个符号不起作用;如果规则不能够让匹配,则该后继的链接的平整会让忽视。比如,在执行一个外表重定向时,
对一个目录级规则集,你或要去“.www” (此处不应有出现“.www”的)。

type|T=MIME-type(强制MIME类型 type)

  强制目标文件的MIME类型为MIME-type。
比如,它好用于模拟mod_alias中的ScriptAlias指令,以中地强制被射目录中的富有文件的MIME类型为“application/x-httpd-cgi”。

nosubreq|NS (仅用于不对内部子请求进行拍卖 no internal sub-request)

  在脚下恳求是一个内部子请求时,此号强制重写引擎跳了该还写规则。比如,在mod_include试图搜索可能的目录默认文件(index.xxx)时,
Apache会内部地产生子请求。对子请求,它不肯定有用之,而且一旦所有规则集还起作用,它还可能会见引发错误。所以,可以就此这个符号来排遣某些规则。

  根据你的待按以下标准:
如果你下了发CGI脚本的URL前缀,以强制其由CGI脚本处理,而对请求处理的出错率(或者开)很高,在这种情景下,可以以这个标记。

nocase|NC (忽略大小写 no case)

  它一旦Pattern忽略大小写,即, 在Pattern与当下URL匹配时,’A-Z’
和’a-z’没有区别。

qsappend|QSA (追加请求串 query string append)

  此标志强制重写引擎在既部分替换串中追加一个请串,而不是简简单单的轮换。如果要经更写规则以伸手串中增信息,就好下此符号。

noescape|NE (在出口中莫针对URI作转义 no URI escaping)

  此标志阻止mod_rewrite对再次写结果使常规的URI转义规则。
一般景象下,特殊字符(如’%’, ‘$’, ‘;’等)会让转义为等值的十六迈入制编码。
此标记可以阻碍这样的转义,以允许百分号等标志出现于出口中,如:

  RewriteRule /foo/(.*) /bar?arg=P1=$1 [R,NE]
可以使’/foo/zed’转向到一个安的请求’/bar?arg=P1=zed’.

passthrough|PT (移交给下一个处理器 pass through)

  此号强制重写引擎将内部结构request_rec中的uri字段设置也
filename字段的价,它就是一个略带修改,使的能够针对来源其他URI到文件称翻译器的
Alias,ScriptAlias, Redirect
等一声令下的输出进行持续处理。举一个可知征其意义的事例:如果假定通过mod_rewrite的重写引擎重写/abc为/def,然后经mod_alias使/def转变吗/ghi,可以这么:

RewriteRule ^/abc(.*) /def$1 [PT]

Alias /def /ghi
  如果简单了PT标记,虽然mod_rewrite运作如常, 即,
作为一个利用API的URI到文件称翻译器,它可以重新写uri=/abc/…为filename=/def/…,但是,后续的mod_alias在试图作URI到文件称的翻译时,则会失灵。

在意: 如果急需混合使用不同之含有URI到文件称翻译器的模块时,
就必利用这标记。。混合使用mod_alias和mod_rewrite就是个典型的例证。

For Apache hackers

  如果手上Apache
API除了URI到文件名hook之外,还有一个文书称及文件称之hook,
就未需要这个符号了!
但是,如果无如此一个hook,则是号是绝无仅有的化解方案。 Apache
Group讨论过此问题,并于Apache 2.0 版本被见面增多这样一个hook。

skip|S=num (跳了后继的平整 skip)

  此标志强制重写引擎跳了手上相当规则后的num个规则。
它可以兑现一个伪if-then-else的构造:
最后一个条条框框是then从句,而为超越了之skip=N个规则是else从句.
(它和’chain|C’标记是不同之!)

env|E=VAR:VAL (设置环境变量 environment variable)

  此标志使环境变量VAR的价也VAL,
VAL可以涵盖可扩大的反向引用的正则表达式$N和%N。
此标记可以频繁采取以安多只变量。这些变量可以当其后多情下深受间接引用,但日常是在XSSI
(via ) or CGI (如 $ENV{’VAR’})中,
也可当继的RewriteCond指令的pattern中通过%{ENV:VAR}作引用。使用它们好由URL中剥离并记住有消息。

cookie|CO=NAME:VAL:domain[:lifetime[:path]] (设置cookie)

  它以客户端浏览器上安装一个cookie。 cookie的称号是NAME,其值是VAL。
domain字段是该cookie的域,比如’.apache.org’,
可选取的lifetime是cookie生命期的分钟数,可选的path是cookie的路子。

  3)、RewriteCond TestString CondPattern [flags]

  Rewritecond指令定义一长条规则条件。在一如既往漫长rewriterule指令前面可能会见生出雷同漫漫或者基本上修rewritecond指令,只有当自身模板匹配成功还这些原则也满足时(即RewriteRule中的pattern匹配成功),规则条件才于以叫当下URL处理。

  1、TestString是一个纯文本之字符串

  • 足对pattern反往引用$N(N=0~9),紧跟以RewriteCond后面的RewriteRule正则表达式中第N个括号中之始末
  • 反向引用%N(N=0~9),表示RewriteCond中CondPattern中第N对括号被之情节
  • 服务器变量%{VARNAME}

  2、CondPattern是原则pattern,一个采用被目前实例TestString的正则表达式。即TestString与原则pattern条件进行匹配。如果匹配则RewriteCond的价值吗Rrue,反的邪False

好运用以下特殊变量(可使用’!’实现反转):

‘>CondPattern’ (大于)
将condPattern当作一个惯常字符串,将它们和TestString进行较,当TestString
的字符大于CondPattern为确实。

‘=CondPattern’ (等于)
将condPattern当作一个平淡无奇字符串,将它和TestString进行比,当TestString
与CondPattern完全相同时也真.如果CondPattern只是 “” (两独引号紧挨在一起)
此时需TestString 为空字符串方为实在。

‘-d’ (是否也目录)
将testString当作一个目录名,检查她是不是在与是否是一个目。

‘-f’ (是否是regular file)
将testString当作一个文件称,检查她是不是存在和是否是一个regular文件。

‘-s’ (是否为长不为0的regular文件)
将testString当作一个文书称,检查她是不是留存和是否是一个长短大于0的regular文件。

‘-l’ (是否也symbolic link)
将testString当作一个文本称,检查她是不是是和是否是一个 symbolic link。

‘-F’ (通过subrequest来检查有文件是否只是看)
检查TestString是否是一个官方的文件,而且通过服务器范围外之眼前设置的访问控制进行访问。这个检查是经过一个中subrequest完成的,
因此待小心使用这个作用为降服务器的性。

‘-U’ (通过subrequest来检查有URL是否有)
检查TestString是否是一个法定的URL,而且通过服务器范围外之当前装的访问控制进行走访。这个检查是经过一个内subrequest完成的,
因此要小心用这职能为降低服务器的特性。

   3、[flags]举凡第三单参数,多单标志之间用逗号隔开

’nocase|NC’ (不分轻重缓急写)
  在扩张后的TestString和CondPattern中,比较常无分文本的尺寸写。注意,这个标志对文件系统和subrequest检查并未影响.

’ornext|OR’ (建立与生一个规格的还是的关系)
  默认的情况下,二个规格里是AND的干,用之标志将涉及转移呢OR。

 

  4)、Rewrite时服务器变量(仅列出少数)

HTTP headers:HTTP_USER_AGENT,  HTTP_REFERER,  HTTP_COOKIE,
 HTTP_HOST,  HTTP_ACCEPT

connection & request:REMOTE_ADDR,  QUERY_STRING

server internals::DOCUMENT_ROOT,  SERVER_PORT,  SERVER_PROTOCOL

system stuff: TIME_YEAR,  TIME_MON,  TIME_DAY

 

  5)、简单正则表达式规则

. 匹配任何单字符

[chars] 匹配字符串:chars

[^chars] 不匹配字符串:chars

text1|text2 可摘的字符串:text1要text2

? 匹配0到1个字符

* 匹配0到多单字符

+ 匹配1到大半只字符

^ 字符串开始标志

$ 字符串结束标志

\n 转义符标志

 【注意】:一代Apache渴求URL有斜杠而二代Apache却休容许,因此使用 ^/?

 

4、例子解析

例1(简单例子):

(在.htaccess里开展规制重写)

RewriteEngine ON 
RewriteRule  ^user/(w+)/?$user.php?id=$1

^:输入的启幕  以user/开头请求的地点

(w+):提取所有的假名,传给$1

/?:可选斜杠

$:结束符

替换为:user.php?id=*

留神:有些apache(具体哪个版本忘啦)不配合简写模式 w+ =>
[a-zA-Z_-]

 例2(禁止IE和Opera浏览器访问):

RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Opera [NC]
RewriteRule ^.* - [F,L]       #'-'表示不替换URL

例3(不合法途径返回首页):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

例4(防盗链):

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+.)?mysite.com/ [NC]       #判断请求的是否是自己的域名
RewriteCond %{HTTP_REFERER} !^$                     #{HTTP_REFERER}不为空
RewriteRule .*.(jpe?g|gif|bmp|png)$ nohotlink.jpg [L]      #返回警告图片

例5(改变访问URL目录名):

纵使潜伏真实的目录名字

RewriteEngine On
RewriteRule ^/?old_dir/([a-z\.]+)$  new_dir/$1 [R=301,L]
#new_dir为真正目录

例6(创建无文件后缀链接):

RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f #判断该后缀文件是否存在
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.html -f #判断该后缀文件是否存在
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]

例7(限制只能显示图片):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME}  !^.*\.(gif|jpg|jpeg|png|swf)$
RewriteRule .*$ - [F,L]

例8(文件不设有重定向404):

RewriteEngine on
RewriteCond  %{REQUEST_FILENAME}  !f
RewriteCond  %{REQUEST_FILENAME}  !d
RewriteRule .? /404.php [L]

 

 (以上是自己的一部分意和总,若有欠缺或失实的地方要各位指出)

作者:这就是说一叶随风

声称:以上仅象征我于做事学习中某一时间内总的意还是结论。转载时要于文章页面明显位置给起本文链接