共计 3988 个字符,预计需要花费 10 分钟才能阅读完成。
本文目录:
1.1 URL 重写简介
1.2 if 指令
1.3 rewrite 指令
1.4 URL 重写和反向代理的区别
1.1 简介
url 重写由 ngx_http_rewrite_module 模块提供,默认会安装,但该模块功能的实现需要 pcre。URL 重写技术不仅要求掌握几个指令的语法、熟悉简单的正则表达式,还需要尽量熟悉 nginx 的各个变量的意义,熟悉的变量越多越好。大多数需要用到的变量都是 http_core 模块提供的,它们的意义参见官方手册http_core 内置变量。
rewrite 模块主要有 break、return、set、rewrite 和 if 这 5 个指令。
- break 的作用是完成当前的作用集,不再执行 rewrite 指令
- return 返回状态码。可用的状态码有 204/301/302/303/307/308/400/402-406/408/410-411/413/416/500-504。return 三种语法:
return code [text]; return code URL; return URL;
- set 用于定义变量。赋给变量的值可以是一个变量、文本及文本变量的组合(语法:set variable value;)
- if 用于设定判断条件。格式为 if (condition) {}
- rewrite 用于设定 URL 重写规则(语法:rewrite regex replacement [flag];)
1.2 if 指令
if 不支持嵌套,不支持 ”&&” 和 ”||” 多目运算符。语法为:
if (condition) {}
测试条件可以如下定义:
(1). 变量的比较可以使用 ”=” 和 ”!=” 运算符。
(2). 正则匹配可以使用 ”~” 和 ”~*”, 前者表示区分大小写的正则匹配,后者表示不区分大小写的匹配。
(3). 正则匹配可以在前面加上感叹号 ”!~” 和 ”!~*” 表示取反,即不匹配。
(4). “-f” 和 ”!-f” 判断文件是否存在。
(5). “-d” 和 ”!-d” 判断目录是否存在。
(6). “-e” 和 ”!-e” 判断文件或目录或软链接是否存在。
(7). “-x” 和 ”!-x” 判断文件是否可执行。
if 支持的正则表达式可以使用 $1 至 $9 来实现反向引用。
以下为几个示例:
# 当使用 IE 浏览器访问时,重定向到 /msie/ 目录下的对应文件
if ($http_user_agent ~ MSIE) {rewrite ^(.*)$ /msie/$1 break;
}
# 当 http 请求的方法为 POST,则直接返回 405 状态码,即 Method not Allowed
if ($request_method = POST) {return 405;
}
# 当请求的资源文件不存在,则直接退出当前匹配,并代理至本机,这种情况下由本机来提供服务,如提供错误页面
if (!-f $request_filename) {break;
proxy_pass http://127.0.0.1;
}
# 当访问的是 linuxidc.com 下任意主机,则重定向到 www.linuxidc.com 主机下的对应目录
if ($http_host ~* "^(.*)\.linuxidc\.com$") {set $domain $1;
rewrite ^(.*) http://www.linuxidc.com/$domain/ break;
}
上面最后一种URL 重写后的 URL 为一个新的主机名站点,但使用 URL 重写的效率比较低下,远不如直接为此站点独立定义一个虚拟主机。所以改写为:
server {listen 80;
server_name .linuxidc.com;
return 302 http://www.linuxidc.com/$request_uri;
}
server {listen 80;
server_name www.linuxidc.com;
}
1.3 rewrite 指令
rewrite 可以写在 server 段、location 段和 if 段。语法:
rewrite regexp replacement [flag]
如果 replacement 部分以 ”http://” 或 ”https://” 或 ”$schema” 开头,则直接临时重定向,见下表中的 redirect 标记。
flag 是标记。有 4 种标记,它们的作用如下表。
flag | 说明 |
---|---|
last | 停止处理当前上下文中的其他重写模块指令,并为重写后的 uri 再次进行上下文的匹配 |
break | 和 break 指令一样,都是停止处理当前上下文中的其他重写模块指令 |
redirect | 返回临时重定向状态码 302。当 replacement 部分不是以 ”http://” 或者 ”https://” 或者 ”$schema” 开头的时候使用,”$schema” 变量表示使用的是什么协议 |
permanent | 返回永久重定向状态码 301 |
以上 flag 中,last 和 break 用来实现 URL 改写,此时浏览器中的地址不会改变,但实际上在服务器上访问的资源和路径已经改变了。redirect 和 permanent 用来实现 URL 跳转,浏览器中的地址会改变为跳转后的地址。
在使用 proxy_pass 指令时要使用 break 标记。last 标记在本条 rewrite 规则执行完后,继续在当前上下文对重写后的地址发起匹配请求,而 break 则在本次匹配完成后停止再次匹配。例如下面的两条重写规则。
rewrite "^/bbs/(.*)/images/(.*)\.jpg$" www.linuxidc.com/bbs/$2/images/$1.jpg last;
rewrite "^/bbs/(.*)/images/(.*)\.jpg$" www.linuxidc.com/bbs/$2/images/$1.jpg break;
如果访问的是 www.linuxidc.com/bbs/a/images/b.jpg 则重写后为 www.linuxidc.com/bbs/b/images/a.jpg,但是重写后的地址仍然可以匹配到规则^/bbs/(.*)/images/(.*)\.jpg$
,此时如果使用 last 标记,则会再次进行重写,最终导致 URL 重写循环,nginx 默认支持 10 次循环,然后返回 500 状态码。而如果使用 break 标记,则在重写完成后不会再次匹配重写。
例如,下面的重写示例将会使得任意以 linuxidc.com 结尾的访问重定向到 www.linuxidc.com。
server_name www.linuxidc.com;
rewrite (.*).linuxidc.com www.linuxidc.com permanent;
下面的重写实例将使得 www.linuxidc.com/bbs/* 的访问都重定向到 www.linuxidc.com/forum/*。
server {listen 80;
server_name www.linuxidc.com;
location /{root /www/linuxidc/;
index index.html;
rewrite "/bbs/(.*)" "/forum/$1" last;
}
}
1.4 URL 重写和反向代理的区别
URL 重写和反向代理都能将请求转发到其他主机上。但它们有很大的区别。
1.URL 重写可以实现一些反向代理不能实现的转发。
2.URL 重写可以实现浏览器地址改变。
3. 反向代理更多的配合 upstream 实现负载均衡。URL 重写无法直接通过转发实现负载均衡。
4. 还有很多其他的区别,无需关心它们的区别,当某种需求既可以 URL 重写实现,也可以反向代理实现,随便用一种方法即可。
下面关于 Nginx 的文章您也可能喜欢,不妨参考下:
Nginx 403 forbidden 的解决办法 http://www.linuxidc.com/Linux/2017-08/146084.htm
CentOS 7 下 Nginx 服务器的安装配置 http://www.linuxidc.com/Linux/2017-04/142986.htm
CentOS 上安装 Nginx 服务器实现虚拟主机和域名重定向 http://www.linuxidc.com/Linux/2017-04/142642.htm
CentOS 6.8 安装 LNMP 环境(Linux+Nginx+MySQL+PHP)http://www.linuxidc.com/Linux/2017-04/142880.htm
Linux 下安装 PHP 环境并配置 Nginx 支持 php-fpm 模块 http://www.linuxidc.com/Linux/2017-05/144333.htm
Nginx 服务的 SSL 认证和 htpasswd 认证 http://www.linuxidc.com/Linux/2017-04/142478.htm
Ubuntu 16.04 上启用加密安全的 Nginx Web 服务器 http://www.linuxidc.com/Linux/2017-07/145522.htm
Linux 中安装配置 Nginx 及参数详解 http://www.linuxidc.com/Linux/2017-05/143853.htm
Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm
CentOS 7.2 下 Nginx+PHP+MySQL+Memcache 缓存服务器安装配置 http://www.linuxidc.com/Linux/2017-03/142168.htm
CentOS6.9 编译安装 Nginx1.4.7 http://www.linuxidc.com/Linux/2017-06/144473.htm
Nginx ��详细介绍:请点这里
Nginx 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147766.htm