rewrite语法格式:
rewrite regex replacement [flag];
任何rewrite规则的第一部分都是一个正则表达式,正则表达式中使用圆括号定义的部分可以被位置变量引用,位置变量的值取决于在正则表达式中圆括号定义的顺序;
rewrite的第二部分是被重写后的URI,该URI可以包含位置变量引用第一部分圆括号中定义的内容。
像下面的规则:
rewrite ^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$ /data?file=$3.$4 last;
表达式 | 说明 |
---|---|
. | 匹配除换行符以外的其它任意字符 |
? | 前一个字符匹配0次或1次 |
+ | 前一个字符匹配1次或多次 |
* | 前一个字符匹配0次或多次 |
\d | 匹配数字 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
{n} | 前一个字符匹配n次 |
{n,} | 前一个字符匹配n次或更多次 |
[n] | 匹配方括号中的字符 |
假如,在“/usr/local/nginx/html/pc/static/”路径下有“index.html”和“index1.html”,使用rewrite进行重写:
server {
listen 80;
server_name 192.168.18.132;
root /usr/local/nginx/html;
index index.html index.htm;
rewrite ^(.*) /pc/static/$1 break;
}
因为Nginx的根路径为“/usr/local/nginx/html”,要访问“pc/static”路径下的文件,则需要在浏览器地址栏中写上文件的完整路径,如“http://192.168.18.132/pc/static/index.html”。经过rewrite重写后,只需要在浏览器中直接访问文件即可:
# curl http://192.168.18.132/index.html
例子中的rewrite规则,也可以这样写:“rewrite ^ /pc/static/$request_uri break;
”,结果是一样的。
比如,想在用户访问到不存在的页面时,都将其跳转到主页上,防止出现404等。配置如下:
server {
listen 80;
server_name 192.168.18.132;
location / {
root /usr/local/nginx/html;
index index.html index.htm;
rewrite ^(.*)$ /index.html break;
}
}
比如,为不同的设备(如PC、Android手机等)设定了不同的下载页面,希望通过在浏览器地址栏输入带变量的URI时,可以跳转到对应的下载页面:
server {
listen 80;
server_name 192.168.18.132;
root /usr/local/nginx/html;
index index.html index.htm;
location /download {
if ($query_string ~* 'device=(.*?)$') {
set $dir $1;
rewrite '^/download.*?$' /data/$dir? permanent;
}
}
location /data {
try_files $uri $uri/ @default;
}
location @default {
return 200 "Hello World!";
}
}
分别为pc、ios、android设定了各自的主页,如下:
# tree /usr/local/nginx/html/data/
/usr/local/nginx/html/data/
├── android
│ └── index.html
├── ios
│ └── index.html
└── pc
├── index.html
当在浏览器地址栏访问“http://192.168.18.132/download?device=pc”,将会跳转到相应的页面上:
# curl -L -G -d "device=pc" http://192.168.18.132/download
PC
# curl -L -G -d "device=ios" http://192.168.18.132/download
IOS
# curl -L -G -d "device=android" http://192.168.18.132/download
Android
# curl -L -G -d "device=test" http://192.168.18.132/download
Hello World!
注意:
1)配置中的set。由于rewrite指令的第二部分使用位置变量引用正则表达式匹配的内容时,位置变量会从rewrite的第一部分去查找,所以需要将if条件中正则表达式匹配到的内容赋值给常规变量,再在rewrite中引用;
2)注意rewrite规则中,第二部分“/data/$dir?”中的“?”,作用是在跳转后的URI中不显示原URI的“?”后的内容。
return指令经常与error_page组合来为客户端提供一个自定义的HTML格式页面,或者激活一个不同的模块来完成请求的处理。
return指令可以指示一个状态码,带有一些文本的状态码,或者带有URI的状态码。如果只有一个URI,那么状态码被理解为302。在将文本放在状态码之后时,该文本就变成了响应体。如果使用了URI,那么该URI变成了Location头的值,客户端将会被重定向。
try_files指令将会按照给定的参数顺序查找,第一个匹配的将会使用。当给定的所有文件都不匹配时,可以将请求传递到一个命名location中。
在4.3节的例子中,通过try_files首先查找文件,再查找目录下的文件,最后会传递到命名location:“@default”中,当然也可以是一个普通的location,例如:“/error_page”或者一个自定义的错误页面,如:“/error_page.html”。location中则通过return指令,返回带文本的响应状态码,用来在所有匹配失败时给出某些信息。
需要注意的是,命名location不能嵌套在其它location中,只能在server {}配置段中使用。
例如,通过try_files和return给出一个error_page:
location / {
try_files $uri $uri/ /error_page;
}
location /error_page {
return 404 "Page Not Found!"
}
或者返回一个自定义的HTML页面:
location / {
try_files $uri $uri/ /404.html;
}
或者将请求转发到其它地址:
location / {
try_files $uri $uri/ @defaultweb;
}
location @defaultweb {
return 301 $scheme://www.example.com;
}
或者在命名location中使用反向代理:
location / {
try_files $uri $uri/ @defaultweb;
}
location @defaultweb {
proxy_pass http://webserver;
}
server {
listen 80;
server_name www.example.com;
rewrite ^(.*)$ https://$host$1 permanent;
}