重写规则
【重写规则的作用范围】
- 可以使用在Apache主配置文件httpd.conf中
- 可以使用在httpd.conf里定义的虚拟主机配置中
- 可以使用在基本目录的跨越配置文件.htaccess中
【重写规则的应用条件】
只有当用户的WEB请求最终被导向到某台WEB服务器的Apache后台,则这台WEB服务器接受进来的请求,根据配置文件该请求是主配置还是虚拟主机,再根据用户在浏览器中请求的URI来配对重写规则并且根据实际的请求路径配对.htaccess中的重写规则。最后把请求的内容传回给用户,该响应可能有两种:
对浏览器请求内容的外部重定向(Redirect)到另一个URL。让浏览器再次以新的URI发出请求(R=301或者R=302,临时的或是永久的重定向)
如:一个网站有正规的URL和别名URL,对别名URL进行重定向到正规URL,或者网站改换成了新的域名则把旧的域名重定向到新的域名(Redirect)也可能是由Apache内部子请求代理产生新的内容送回给客户[P,L]这是Apache内部根据重写后的URI内部通过代理模块请求内容并送回内容给客户,而客户端浏览器并不知道,浏览器中的URI不会被重写。但实际内容被Apache根据重写规则后的URI得到。
如:在公司防火墙上运行的Apache启动这种代理重写规则,代理对内部网段上的WEB服务器的请求。
【重写规则怎样工作?】
我们假定在编译Apache时已经把mod_rewrite编译成模块,确信你的httpd.conf中有LoadModule rewrite_module libexec/mod_rewrite.so并且在Addmodule中有Addmodule mod_rewrite.c则可以使用重写规则。
当外部请求来到Apache,Apache调用重写规则中的定义来重写由用户浏览器指定请求的URI,最后被重写的URI如果是重定向,则送由浏览器作再一次请求;如果是代理则把重写后的URI交给代理模块请求最终的内容(Content),最后把内容送回给浏览器。
【Apache】
1.检测Apache是否支持mod_rewrite:LoadModule rewrite_module
2.让apache服务器支持.htaccess
Options FollowSymLinks
AllowOverride None
改为
Options FollowSymLinks
AllowOverride All
Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言。可基于服务器级的(httpd.conf)和目录级的(.htaccess) 两种方式:
方法有两种一种是编译apache的时候就直接安装rewrite模块,另一种是编译apache时以DSO模式安装apache,然后再利用源码和apxs来安装rewrite模块。
基于服务器级的(httpd.conf)有两种方法,
一种是在httpd.conf的全局下直接利用RewriteEngine on来打开rewrite功能;
NameVirtualHost 192.168.100.8:80
ServerAdmin [email protected]
DocumentRoot "/web/webapp"
ServerName www.colorme.com.cn
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.colorme.com.cn [NC]
RewriteCond %{HTTP_HOST} !^203.81.23.202 [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.colorme.com.cn/ [L]
一种是在局部里利用RewriteEngine on来打开rewrite功能。
下面是一个典型的htaccess文件
开启URL重写
RewriteEngine on
URL重写的作用域
RewriteBase /path/to/url
满足怎样的条件
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
应用怎样的规则
RewriteRule .? http://www.example.com%{REQUEST_URI} [R=301,L]
来看看RewriteCond,首先有一个%,因为{HTTP_HOST}是一个apache变量,需要用%来指示。从!开始就是匹配的条件,支持 正则。!表示不等于,这句话的意思就是:如果HTTP_HOST不是www.example.com。后面的[NC](no case)表示忽略大小写,常见的还有
L:终止一系列的RewriteCond和RewriteRule
R:触发一个显示的跳转,也可以指定跳转类型,如[R=301]
F:禁止查看特定文件,apache会触发403错误
【Nginx】
见NGINX文档
【IIS】
下载http://www.helicontech.com/download/isapi_rewrite/ISAPI_Rewrite3_0056_Lite.msi
打开C:\Program Files\Helicon\ISAPI_Rewrite3\httpd.conf
选学
【例子】
图片防盗链
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www.)?example.com/ [NC]
RewriteRule .(gif|jpg|png)$ - [F]
=============================================================
网站升级的时候,只有特定IP才能访问,其他的用户将看到一个升级页面
=============================================================
RewriteEngine on
RewriteCond %{REQUEST_URI} !/upgrade.html$
RewriteCond %{REMOTE_HOST} !^24.121.202.30
RewriteRule $ http://www.nbphp.com/upgrade.html [R=302,L]
===================
把老的域名转向新域名
===================
redirect from old domain to new domain
RewriteEngine On
RewriteRule ^(.*)$http://www.yourdomain.com/$1[R=301,L]
=================
引出错误文档的目录
=================
ErrorDocument 400 /errors/badrequest.html
ErrorDocument 404 http://yoursite/errors/notfound.html
ErrorDocument 401 “Authorization Required
常见HTTP状态码
Successful Client Requests
200 OK
201 Created
202 Accepted
203 Non-Authorative Information
204 No Content
205 Reset Content
206 Partial Content
Client Request Redirected
300 Multiple Choices
301 Moved Permanently
302 Moved Temporarily
303 See Other
304 Not Modified
305 Use Proxy
Client Request Errors
400 Bad Request
401 Authorization Required
402 Payment Required (not used yet)
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable (encoding)
407 Proxy Authentication Required
408 Request Timed Out
409 Conflicting Request
410 Gone
411 Content Length Required
412 Precondition Failed
413 Request Entity Too Long
414 Request URI Too Long
415 Unsupported Media Type
Server Errors
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
5.2 Blocking users by IP 根据IP阻止用户访问
order allow,deny
deny from 123.45.6.7
deny from 12.34.5. (整个C类地址)
allow from all
===========
设置默认首页
===========
serve alternate default index page
DirectoryIndex about.html
把一些老的链接转到新的链接上——搜索引擎优化SEO
Redirect 301 /d/file.htmlhttp://www.htaccesselite.com/r/file.html
为服务器管理员设置电子邮件。
ServerSignature EMail
SetEnv [email protected]
============================
Password Protection 密码保护
============================
Official document: Authentication, Authorization and Access Control
假设密码文件为.htpasswd
AuthUserFile /usr/local/safedir/.htpasswd (这里必须使用全路径名)
AuthName EnterPassword
AuthType Basic
两种常见验证方式:
Require user windix
(仅允许用户windix登陆)
Require valid-user
(所有合法用户都可登陆)
Tip: 如何生成密码文件
使用htpasswd命令(apache自带)
第一次生成需要创建密码文件
htpasswd -c .htpasswd user1
之后增加新用户
htpasswd .htpasswd user2
=======================================================================
Enabling SSI Via htaccess 通过htaccess允许SSI(Server Side Including)功能
=======================================================================
AddType text/html .shtml
AddHandler server-parsed .shtml
Options Indexes FollowSymLinks Includes
DirectoryIndex index.shtml index.html
======================================
Blocking users by IP 根据IP阻止用户访问
======================================
order allow,deny
deny from 123.45.6.7
deny from 12.34.5. (整个C类地址)
allow from all
==============================================================
Blocking users/sites by referrer 根据referrer阻止用户/站点访问
==============================================================
例1. 阻止单一referrer: badsite.com
RewriteEngine on
Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} badsite.com [NC]
RewriteRule .* - [F]
例2. 阻止多个referrer: badsite1.com, badsite2.com
RewriteEngine on
Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} badsite1.com [NC,OR]
RewriteCond %{HTTP_REFERER} badsite2.com
RewriteRule .* - [F]
[NC] - 大小写不敏感(Case-insensite)
[F] - 403 Forbidden
注意以上代码注释掉了”Options +FollowSymlinks”这个语句。如果服务器未在 httpd.conf 的 段落设置 FollowSymLinks, 则需要加上这句,否则会得到”500 Internal Server error”错误。
===============================================================================
Blocking bad bots and site rippers (aka offline browsers) 阻止坏爬虫和离线浏览器
===============================================================================
需要mod_rewrite模块
坏爬虫? 比如一些抓垃圾email地址的爬虫和不遵守robots.txt的爬虫(如baidu?)
可以根据 HTTP_USER_AGENT 来判断它们
(但是还有更无耻的如”中搜 zhongsou.com”之流把自己的agent设置为 “Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)” 太流氓了,就无能为力了)
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
RewriteCond %{HTTP_USER_AGENT} ^Bot\ mailto:[email protected] [OR]
RewriteCond %{HTTP_USER_AGENT} ^ChinaClaw [OR]
RewriteCond %{HTTP_USER_AGENT} ^Custo [OR]
RewriteCond %{HTTP_USER_AGENT} ^DISCo [OR]
RewriteCond %{HTTP_USER_AGENT} ^Download\ Demon [OR]
RewriteCond %{HTTP_USER_AGENT} ^eCatch [OR]
RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [OR]
RewriteCond %{HTTP_USER_AGENT} ^Express\ WebPictures [OR]
RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro [OR]
RewriteCond %{HTTP_USER_AGENT} ^EyeNetIE [OR]
RewriteCond %{HTTP_USER_AGENT} ^FlashGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetRight [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetWeb! [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go!Zilla [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go-Ahead-Got-It [OR]
RewriteCond %{HTTP_USER_AGENT} ^GrabNet [OR]
RewriteCond %{HTTP_USER_AGENT} ^Grafula [OR]
RewriteCond %{HTTP_USER_AGENT} ^HMView [OR]
RewriteCond %{HTTP_USER_AGENT} HTTrack [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Stripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} Indy\ Library [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^InterGET [OR]
RewriteCond %{HTTP_USER_AGENT} ^Internet\ Ninja [OR]
RewriteCond %{HTTP_USER_AGENT} ^JetCar [OR]
RewriteCond %{HTTP_USER_AGENT} ^JOC\ Web\ Spider [OR]
RewriteCond %{HTTP_USER_AGENT} ^larbin [OR]
RewriteCond %{HTTP_USER_AGENT} ^LeechFTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mass\ Downloader [OR]
RewriteCond %{HTTP_USER_AGENT} ^MIDown\ tool [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mister\ PiX [OR]
RewriteCond %{HTTP_USER_AGENT} ^Navroad [OR]
RewriteCond %{HTTP_USER_AGENT} ^NearSite [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetAnts [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Net\ Vampire [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Octopus [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Explorer [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Navigator [OR]
RewriteCond %{HTTP_USER_AGENT} ^PageGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^Papa\ Foto [OR]
RewriteCond %{HTTP_USER_AGENT} ^pavuk [OR]
RewriteCond %{HTTP_USER_AGENT} ^pcBrowser [OR]
RewriteCond %{HTTP_USER_AGENT} ^RealDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^ReGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^SiteSnagger [OR]
RewriteCond %{HTTP_USER_AGENT} ^SmartDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperBot [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperHTTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Surfbot [OR]
RewriteCond %{HTTP_USER_AGENT} ^tAkeOut [OR]
RewriteCond %{HTTP_USER_AGENT} ^Teleport\ Pro [OR]
RewriteCond %{HTTP_USER_AGENT} ^VoidEYE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Image\ Collector [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebAuto [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebCopier [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebFetch [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebGo\ IS [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebLeacher [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebReaper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebSauger [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ eXtractor [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ Quester [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebStripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebWhacker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Wget [OR]
RewriteCond %{HTTP_USER_AGENT} ^Widow [OR]
RewriteCond %{HTTP_USER_AGENT} ^WWWOFFLE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]
[F] - 403 Forbidden
[L] - 连接(Link)
==================================================
Change your default directory page 改变缺省目录页面
==================================================
DirectoryIndex index.html index.php index.cgi index.pl
==============
Redirects 转向
==============
单个文件
Redirect /old_dir/old_file.html http://yoursite.com/new_dir/new_file.html
整个目录
Redirect /old_dir http://yoursite.com/new_dir
效果: 如同将目录移动位置一样
http://yoursite.com/old_dir -> http://yoursite.com/new_dir
http://yoursite.com/old_dir/dir1/test.html -> http://yoursite.com/new_dir/dir1/test.html
Tip: 使用用户目录时Redirect不能转向的解决方法
当你使用Apache默认的用户目录,如 http://mysite.com/~windix,当你想转向 http://mysite.com/~windix/jump时,你会发现下面这个Redirect不工作:
Redirect /jump http://www.google.com
正确的方法是改成
Redirect /~windix/jump http://www.google.com
(source: .htaccess Redirect in “Sites” not redirecting: why?
)
========================================================
Prevent viewing of .htaccess file 防止.htaccess文件被查看
========================================================
order allow,deny
deny from all
Adding MIME Types 添加 MIME 类型
AddType application/x-shockwave-flash swf
Tips: 设置类型为 application/octet-stream 将提示下载
===========================================================
Preventing hot linking of images and other file types 防盗链
============================================================
需要mod_rewrite模块
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www/.)?mydomain.com/.*$ [NC]
RewriteRule .(gif|jpg|js|css)$ - [F]
解析:
若 HTTP_REFERER 非空 (来源为其他站点,非直接连接) 并且
若 HTTP_REFERER 非(www.)mydomain.com开头(忽略大小写[NC]) (来源非本站)
对于所有含有 .gif/.jpg/.js/.css 结尾的文件给出 403 Forbidden 错误[F]
也可指定响应,如下例显示替换图片
RewriteRule .(gif|jpg)$ [R,L]
[R] - 转向(Redirect)
[L] - 连接(Link)
==============================================
Preventing Directory Listing 防止目录列表时显示
==============================================
IndexIgnore *
IndexIgnore *.jpg *.gif
Tips:
允许目录列表显示: Options +Indexes
禁止目录列表显示: Options -Indexes
显示提示信息: 页首 文件HEADER, 页尾 文件README
==================
限制PHP上传文件大小
==================
这招在共享空间的服务器上很有用,可以让我的用户上传更大的文件。第一个是设置最大的上传文件大小,第二个是设置最大的POST请求大小,第三个PHP脚本最长的执行时间,最后一个是脚本解析上传文件的最长时间:
php_value upload_max_filesize 20M
php_value post_max_size 20M
php_value max_execution_time 200
php_value max_input_time 200
【基础知识】
htaccess基本语法介绍
开启重写引擎 :RewriteEngine on
设置重写的根目录:RewriteBase / — 说明 :因为定义了这个文件夹,所以对应的替换就有了一个参照。
匹配所有符合条件的请求:RewriteCond — 说明:RewriteCond 定义了一系列规则条件,这个指令可以有一条或者多条,只有用户拿来的url符合这些条件之后,我们的.htaccess才开始接待,否则用户就直接自己去访问所需要的目录了。
========
常量
========
%{HTTP_HOST}表示当前访问的网址,只是指前缀部分,格式是www.xxx.com不包括“http://”和“/”
%{REQUEST_URI}表示访问的相对地址,就是相对根目录的地址,就是域名/后面的成分,格式上包括最前面的“/”
%{REQUEST_FILENAME}
%{HTTP_REFERER}
==========
正则表达式
==========
[] —— 匹配一个字符集合,例如[xyz]可以匹配x, y或者z
[]+ —— 例如[xyz]+会以任何顺序、次数匹配x,y,z的出现
[^] —— 字符表示字符集的补集。[xyz]将匹配没有x,y或者z的字符串
[a-z] —— 连字符(-)表示匹配从字母a到字母z的所有字符串
a{n} —— 指定字母a出现的次数为n次,满足该条件时匹配。例如x{3}仅与xxx匹配
a{n,} —— 指定字母a出现的次数至少为n次,例如x{3,}可以与xxx或者xxxx等匹配
a{n,m} —— 指定a出现的次数至少为n到m次。
() —— 用于将正则表达式分组,满足第一组正则表达式的字符串会被存储在变量$1中,以此类推。如果括号中的不是正则表达式,例如(perishable)?press 将能够匹配有或者没有perishable前缀的press
^ —— 位于行首。注意:和中括号中的[^]意义不同。
$ —— 位于行末
? —— 例如 monzas? 会匹配 monza 或者 monzas,而 mon(za)? 会匹配 mon 或者 monza。又如 x? 会匹配“空字符” 或者 一个x
! —— 逻辑非。例如“!string” 将会匹配除了“string”以外的所有字符串
. —— 表示任意字符串
– —— 命令Apache“不要”重写URL,例如“xxx.domain.com.* – [F]”
- —— 匹配至少一个任意字符,例如G+匹配以G开头、并且后面至少有一个字符的字符串
- —— 匹配零个或多个字符,例如“.”匹配任意字符串
| —— 逻辑“或”,与[OR]不同的是,它只匹配字符串,例如(x|y)匹配x或者y
\ —— 转义字符。可以转义左括号( 尖字符^ 美元符号$ 感叹号! 点. 星号 管道符号| 右括号) 等
. —— 转义为点字符(点字符在正则表达式中可以匹配任意字符)
/* —— 零个或多个正斜杠
.* —— 零个或多个任意字符(即,匹配任意字符串,包括空字符)
^$ —— 匹配“空字符”、“空行”
^.$ —— 匹配任意字符串(仅限一行)
[^/.] —— 匹配既非“正斜杠”也不是“点”的任意字符
[^/.]+ —— 匹配第一个字符既非“正斜杠”也不是“点”,后继字符可以是“正斜杠”或者“点”的字符串
http:// —— 匹配“http://”
^domain. —— 匹配以“domain”开始的字符串
^domain.com$ —— 仅匹配“domain.com”
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
-d —— 测试字符串是否是已存在的目录
-f —— 测试字符串是否是已存在的文件
-s —— 测试字符串所指文件是否有“非零”值
注意:
RewriteRule ^([0-9]+).html?req_id=(.*)$ p.php?id=$1&req_id=$2
?后面部分是不会进入RewriteRule的,需要用QUERY_STRING变量来获取
需求1:将http://www.baidu.com/test/one.html?name=miko重写为http://www.baidu.com/two.html?name=miko,重写语句如下:
RewriteRule ^test/one.html$ two.html [QSA]
需求2:将http://www.baidu.com/test/one.html?name=miko重写为http://www.baidu.com/miko.html,重写语句如下:
RewriteCond %{QUERY_STRING} ^name=(/w+)$
RewriteRule ^test/one.html %1.html
===================================
Apache mod_rewrite规则重写的标志一览
===================================
R[=code](force redirect) 强制外部重定向 强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定,将用缺省的302 HTTP状态码。
F(force URL to be forbidden)禁用URL,返回403HTTP状态码。
G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。
P(force proxy) 强制使用代理转发。
L(last rule) 表明当前规则是最后一条规则,停止分析以后规则的重写。
N(next round) 重新从第一条规则开始运行重写过程。
C(chained with next rule) 与下一条规则关联 如果规则匹配则正常处理,该标志无效,如果不匹配,那么下面所有关联的规则都跳过。
T=MIME-type(force MIME type) 强制MIME类型
NS (used only if no internal sub-request) 只用于不是内部子请求
NC(no case) 不区分大小写
QSA(query string append) 追加请求字符串
NE(no URI escaping of output) 不在输出转义特殊字符例如:RewriteRule /foo/(.*) /bar?arg=P1%3d$1 [R,NE]将能正确的将/foo/zoo转换成/bar?arg=P1=zed
PT(pass through to next handler) 传递给下一个处理例如:RewriteRule ^/abc(.*) /def$1 [PT] # 将会交给/def规则处理Alias /def /ghi
S=num(skip next rule(s)) 跳过num条规则
E=VAR:VAL(set environment variable) 设置环境变量