Nginx 配置之 rewrite 配置

1、什么是 rewrite

Rewrite 及 URL 重写,主要是实现地址重写,以及重定向,就是把输入Web的请求重定向到其他URL的过程。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。

该指令使用的模块是 ngx_http_rewrite_module

rewrite使用场景:

  • URL地址跳转,例如用户访问old.com将其跳转到oldboy.com,或者当用户通过http的方式访问old.com时,将其跳转至https的方式访问oldboy.com。
  • URL伪静态,将动态页面显示为静态页面的一种技术,便于搜索引擎的录入,同时减少动态URL地址对外暴露过多的参数,提升更高的安全性。
  • 搜索引擎SEO优化依赖与URL路径,以便支持搜索引擎录入。
  • 可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的要求。

1.1、rewrite 和 location

rewrite和location的功能有点相像,都能实现跳转,主要区别在于rewrite常用于同一域名内更改获取资源的路径,而location是对一类路径做控制访问和反向代理,可以proxy_pass到其他服务器。很多情况下rewrite也会写在location里,它们的执行顺序是:

  • 执行server块的rewrite指令
  • 执行location匹配
  • 执行选定的location中的rewrite指令

如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超过10次,则返回500 Internal Server Error错误。

rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用。例如 http://seanlook.com/a/we/index.php?id=1&u=str 只对 /a/we/index.php 重写。

2、rewrite 语法

1
2
rewrite regex replacement [flag];
# rewrite 规则 定向路径 重写类型;
  • regex(规则):用来匹配URI的正则 路跨境表达式
  • replacement(定向路径):匹配成功后,用于替换URI中被截取内容的字符串。如果该字符串是以”http://“或者”https://“开头的,则不会继续向下对URI进行其他处理,而是直接返回重写后的URI给客户端。
  • flag(重写类型):用来设置rewrite对URI的处理行为,可选值有如下:
    • last:本条规则匹配完成后,继续向下匹配新的location URL规则;last一般写在server和if中,而break一般使用在location中。
    • break:本条规则匹配完成即终止,不再匹配后面的任何规则;
    • redirect:返回302临时重定向。浏览器地址会显示跳转新的URL地址。
    • permanent:返回301永久重定向。浏览器地址会显示跳转新的URL地址。

作用域:server,location,if。

2.1、Rewrite 常用全局变量

变量 说明
$args 变量中存放了请求URL中的请求指令。比如http://192.168.200.133:8080?arg1=value1&arg s2=value2中的”arg1=value1&arg2=value2”,功能和$query_string一样
$http_user_agent 变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息)
$host 变量存储的是访问服务器的server_name值
$document_uri 变量存储的是当前访问地址的URI。比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server",功能和$uri一样
$document_root 变量存储的是当前请求对应location的root值,如果未设置,默认指向Nginx自带html目录所在位置
$content_length 变量存储的是请求头中的Content-Length的值
$content_type 变量存储的是请求头中的Content-Type的值
$http_cookie 变量存储的是客户端的cookie信息,可以通过add_header Set-Cookie ‘cookieName=cookieValue’来添加cookie数据
$limit_rate 变量中存储的是Nginx服务器对网络连接速率的限制,也就是Nginx配置中对limit_rate指令设置的值,默认是0,不限制。
$remote_addr 变量中存储的是客户端的IP地址
$remote_port 变量中存储了客户端与服务端建立连接的端口号
$remote_user 变量中存储了客户端的用户名,需要有认证模块才能获取
$scheme 变量中存储了访问协议
$server_addr 变量中存储了服务端的地址
$server_name 变量中存储了客户端请求到达的服务器的名称
$server_port 变量中存储了客户端请求到达服务器的端口号
$server_protocol 变量中存储了客户端请求协议的版本,比如”HTTP/1.1”
$request_body_fifile 变量中存储了发给后端服务器的本地文件资源的名称
$request_method 变量中存储了客户端的请求方式,比如”GET”,”POST”等
$request_fifilename 变量中存储了当前请求的资源文件的路径名
$request_uri 变量中存储了当前请求的URI,并且携带请求参数,比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server?id=10&name=zhangsan

2.2、nginx 常用正则表达式

  • . : 匹配除换行符以外的任意字符
  • ? : 重复0次或1次
  • + : 重复1次或更多次
  • * : 重复0次或更多次
  • \d :匹配数字
  • ^ : 匹配字符串的开始
  • $ : 匹配字符串的结束
  • {n} : 重复n次
  • {n,} : 重复n次或更多次
  • [c] : 匹配单个字符c
  • [a-z] : 匹配a-z小写字母的任意一个

3、示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
# 访问 /last.html 的时候,页面内容重写到 /index.html 中,并继续下面的匹配
rewrite /last.html /index.html last;

# 访问 /break.html 的时候,页面内容重写到 /index.html 中,并停止后续的匹配
rewrite /break.html /index.html break;

# 访问 /redirect.html 的时候,页面直接302定向到 /index.html中
rewrite /redirect.html /index.html redirect;

# 访问 /permanent.html 的时候,页面直接301定向到 /index.html中
rewrite /permanent.html /index.html permanent;

# 把 /html/*.html => /post/*.html ,301定向
rewrite ^/html/(.+?).html$ /post/$1.html permanent;

# 把 /search/key => /search.html?keyword=key
rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent;
}

last 和 break 区别:

  • location里一旦返回break则直接生效并停止后续的匹配location
  • last 在本条 rewrite 规则执行完毕后,会对其所在的 server{…} 标签重新发起请求

Nginx 配置之 rewrite 配置
https://flepeng.github.io/040-Nginx-11-安装和配置-Nginx-配置之-rewrite-配置/
作者
Lepeng
发布于
2016年1月1日
许可协议