rewrite配置在server{}、location{}、if{}段中 ,对Url中除去域名和参数的字符串起作用
一、语法:rewrite regex replacement [flag];
regex:服务器接收到的请求地址
replacement:重写后的请求地址
[flag]标志位:
last: 表示完成rewrite
break: 表示跳出rewrite
redirect: 返回302临时重定向
permanent: 返回301永久重定向
二、rewrite与location
rewrite是在同一域名内更改获取资源的路径
location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。
三、服务器解析url请求的过程
st=>start: URL请求
op1=>operation: server{}的rewrite
cond1=>condition: 是否重写url
op2=>operation: location匹配
cond2=>condition: 是否重写
op3=>operation: location{}的rewrite
cond3=>condition: 是否重写
op4=>operation: 响应结果
e=>end: 结束
st->op1->cond1
cond1(yes,right)->op1
cond1(no)->op2->cond2
cond2(yes,right)->op1
cond2(no)->op3->cond3
cond3(yes,right)->op1
cond3(no)->op4->e
这样的循环超过10次,服务器会返回500错误提示
四、相关指令
set : 设置变量
return : 返回状态码
if(条件){} :设定条件,再进行重写
if条件判断写法:
1: =
用于字符串比较
2: ~
区分大小写正则匹配;
~*
不区分大小写正则匹配
3: -f
是否为文件
-d
是否为目录
-e
是否存在
4: 当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
eg.
if ($remote_addr = 192.168.1.100) {
return 403;
}
if ($http_user_agent ~ MSIE) {
rewrite ^.*$ /ie.htm;
break; #不break会循环重定向
}
if (!-e $document_root$fastcgi_script_name) {
rewrite ^.*$ /404.html break;
}
五、重写示例
Goods-3.html ---->Goods.php?goods_id=3
goods-([\d]+)\.html ---> goods.php?goods_id =$1
location /ecshop {
index index.php;
rewrite goods-([\d]+)\.html$ /ecshop/goods.php?id=$1;
rewrite article-([\d]+)\.html$ /ecshop/article.php?id=$1;
rewrite category-(\d+)-b(\d+)\.html /ecshop/category.php?id=$1&brand=$2;
rewrite category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d\.]+)\.html /ecshop/category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5;
rewrite category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d+\.])-(\d+)-([^-]+)-([^-]+)\.html /ecshop/category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8;
}
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
} //防盗链
}
http {
# 定义image日志格式
log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
# 开启重写日志
rewrite_log on;
server {
root /home/www;
location / {
# 重写规则信息
error_log logs/rewrite.log notice;
# 注意这里要用‘’单引号引起来,避免{}
rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
# 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
set $image_file $3;
set $image_type $4;
}
location /data {
# 指定针对图片的日志格式,来分析图片类型和大小
access_log logs/images.log mian;
root /data/images;
# 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
try_files /$arg_file /image404.html;
}
location = /image404.html {
# 图片不存在返回特定的信息
return 404 "image not found\n";
}
}
六、全局变量
$args : #这个变量等于请求行中的参数,同$query_string
$content_length : 请求头中的Content-length字段。
$content_type : 请求头中的Content-Type字段。
$document_root : 当前请求在root指令中指定的值。
$host : 请求主机头字段,否则为服务器名称。
$http_user_agent : 客户端agent信息
$http_cookie : 客户端cookie信息
$limit_rate : 这个变量可以限制连接速率。
$request_method : 客户端请求的动作,通常为GET或POST。
$remote_addr : 客户端的IP地址。
$remote_port : 客户端的端口。
$remote_user : 已经经过Auth Basic Module验证的用户名。
$request_filename :当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name : 服务器名称。
$server_port : 请求到达服务器的端口号。
$request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri : 与$uri相同。
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/tes…
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php