有时候,我们看见nginx里面有各种rewrite指令,但就是不知道什么意思,今天我们就来理一下。
rewrite指令语法
Syntax: | rewrite regex replacement [flag]; |
---|---|
Default: | — |
Context: | server , location , if |
如果指定的正则表达式与请求URI匹配,则URI将按照replacement字符串中的指定进行更改。
rewrite指令按照它们在配置文件中的出现顺序依次执行。可以使用flag终止指令的进一步处理。
如果replacement字符串以“http://”, “https://”或“$scheme”开头,则处理将停止,并将重定向返回给客户端。
flag参数
- last:停止处理当前的ngx_http_rewrite_module指令集,并开始搜索与更改后的URI相匹配的新位置;
- break:与break指令一样,停止处理当前的ngx_http_rewrite_module指令集;
- redirect :返回带有302代码的临时重定向; 如果replacement字符串不是以“ http://”,“ https://”或”$scheme”开头,则使用该字符串;
- permanent:返回带有301代码的永久重定向
案例:
我们在本地配置一个虚拟服务器。
server {
listen 80;
server_name test.rewrite.com;
index index.html index.htm index.php;
root /www/rewrite;
}
在rewrite目录创建一个index.html
$ /www/rewrite> cat index.html
hello world
再到/etc/hosts里面配置一个域名映射
127.0.0.1 test.rewrite.com
然后我们访问一下
案例1:静态文件目录
我们在前台显示的是/res/upload/dir_name/,其实我们的图片资源是放在/resource/upload/dir_name/下面。
访问图片失败,那么我们加上对应的rewrite规则试下
location /{
rewrite ^/res/upload/([a-zA-Z]+)/([0-9a-zA-Z]+).((jpeg|jpg|png|gif))$ /resource/upload/$1/$2.$3 last;
}
下面我们解释下上面的路由规则:
我们可以看到有/res/upload/直接替换成了/resource/upload/, 后面还有$1,$2,$3变量,这是属于正则的反向引用了。
- $1匹配正则表达式的第一个()中的内容,也就是([a-zA-Z]+) 对应到我们的url就是img。
- $2匹配正则表达式的第二个(),也就是([0-9a-zA-Z]+), 对应我们的url就是1。
- $3匹配正则表达式的第三个(),也就是((jpeg|jpg|png|gif)),对应我们的url就是jpeg,并且我们最后用了一个$符号,说明url只能以jpeg|jpg|png|gif结尾。
那么我们尝试着创建一个index.html来看一下
$ /w/rewrite> cd resource/upload/img/
$ /w/r/r/u/img> ls -l
total 632
-rw-r–r–@ 1 staff staff 65591 2 23 15:34 1.jpeg
-rw-r–r–@ 1 staff staff 253354 2 23 15:35 2.jpeg
$ /w/r/r/u/img> echo ‘test html’ >index.html
$ /w/r/r/u/img> cat index.html
test html
将url的某些路径改为参数 ,例如/user/1 改为show?user=1
增加以下重写规则
location /{ rewrite ^/index.html/([a-zA-z]+)/([0-9]+)$ /index.html?$1=$2 last; }
按照这个重写规则,我们可以在index.html后面加任何参数。例如
flag参数详解
location /res{ rewrite ^/res/upload/([a-zA-Z]+)/([0-9a-zA-Z]+).((jpeg|jpg|png|gif))$ /resource/upload/$1/$2.$3 last; } location /resource{ rewrite ^/resource/upload/([a-zA-Z]+)/([0-9a-zA-Z]+).((jpeg|jpg|png|gif))$ /resource1/upload/$1/$2.$3 break; }
我们的域名后面接得是/res/upload/img/1.jpeg 那么就匹配上了location /res,重写后的路径为/resource/upload/img/1.jpeg,但是因为我们的flag是last,所以它就会接着匹配,结果又匹配到了location /resource,重写后的路径为/resource1/upload/img/1.jpeg 这时候就访问不到图片了,如果我们想在location /res重写后不继续匹配location,那么我们可以将last改为break。
location /res{ rewrite ^/res/upload/([a-zA-Z]+)/([0-9a-zA-Z]+).((jpeg|jpg|png|gif))$ /resource/upload/$1/$2.$3 break; } location /resource{ rewrite ^/resource/upload/([a-zA-Z]+)/([0-9a-zA-Z]+).((jpeg|jpg|png|gif))$ /resource1/upload/$1/$2.$3 break; }
那么这时候就能访问到了。通过上面的案例,我们讲解到了last和break标志。那么接下来我们看下redirect
location /res{
rewrite ^/res/upload/([a-zA-Z]+)/([0-9a-zA-Z]+).((jpeg|jpg|png|gif))$ /resource/upload/$1/$2.$3 redirect;
}
我们可以发现redirect会返回302临时重定向,浏览器地址会显示跳转后的URL地址。我们再接着看permanent标志。
location /res{
rewrite ^/res/upload/([a-zA-Z]+)/([0-9a-zA-Z]+).((jpeg|jpg|png|gif))$ /resource/upload/$1/$2.$3 permanent;
}
返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。
总结:
只要熟悉正则表达式,rewrite就相对来说比较容易了。
参考链接:
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite