Nginx中的Location和Rewrite

一、location

1. location的分类

location大致可以分为三类:

  1. 精准匹配:location = / {...}
  2. 一般匹配:location / {...}
  3. 正则匹配:location ~ / {...}

2. location常用的匹配规则

匹配规则 说明
= 进行普通字符精确匹配,也就是完全匹配
^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location
~ 区分大小写的匹配
~* 不区分大小写的匹配
!~ 区分大小写的匹配取非
!~* 不区分大小写的匹配取非

3. location优先级

  1. 精确匹配 =
  2. 前缀匹配 ^~
  3. 按文件中的顺序的正则匹配 /~ 或 ~/*
  4. 匹配不带任何修饰的一般前缀匹配
  5. /通用匹配

总结:

(location = 完整路径) > (location ^~ 路径) > (location ~[*] 正则顺序) > (location 部分起始路径)> (location /)

4. location的示例说明

  1. location = / {}

    =为精确匹配 / ,主机名后面不能带任何字符串,比如访问 / 和/data,则 / 匹配,/data不匹配。

    再比如 location = /abc ,则只匹配/abc,/abc/或/abcd不匹配;

    若 location /abc ,则即匹配/abc、/abcd/同时也匹配/abc/。

  2. location / {}

    因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求,比如访问 / 和 /data,则 / 匹配,/data也匹配;

    但若后面是正则表达式会和最长字符串优先匹配(最长匹配)。

  3. location /documents/ {}

    匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它location,只有其它location后面的正则表达式没有匹配到时,才会采用这一条。

  4. location /documents/abc {}

    匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它location,只有其它location后面的正则表达式没有匹配到时,才会采用这一条。

  5. location ^~ /images/ {}

    匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。

  6. location ~* .(gif|jpg|jpeg)$ {}

    匹配所有以gif/jpg/jpeg结尾的请求。

    然后,所有请求 /images/ 下的图片会被 location ^~ /images/处理,因为 ^~ 的优先级更高,所以到达不了这一条正则。

  7. location /images/abc {}

    最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它location,会发现 ^~ 和 ~ 存在。

  8. location ~ /images/abc {}

    匹配以/images/abc开头的,优先级次之,只有去掉location ^~ /images/ 才会采用这一条。

  9. location /images/abc/1.html {}

    匹配/images/abc/1.html文件,如果和正则location ~ /images/abc/1,html 相比,正则优先级更高。

5. 必选规则

实际网站使用中,至少有三个匹配规则定义

  1. 匹配根

    直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。

    可以是一个静态首页,也可以直接转发给后端应用服务器。
location = / {
root html;
index index.html index.htm;
}
  1. 处理静态文件请求

    这是nginx作为http服务器的强项。

    有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用。
location ^~ /static/ {
root /webroot/static/;
} location ~* \.(html|gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
  1. 通用规则

    比如用来转发带.php/.jsp后缀的动态请求到后端应用服务器,非静态文件请求就默认是动态请求。
location / {
proxy_pass http://tomcat_server;
}

二、Nginx Rewrite

1. Rewrite概述

rewrite功能就是使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。

比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。

2. Rewrite的跳转场景

  1. 调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。
  2. 为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
  3. 网址换新域名后,让旧的访问跳转到新的域名商。例如,访问京东的360buy.com会跳转到jd.com。
  4. 服务端某些业务调整,比如根据特殊变量、目录、客户端的信息进行URL调整等。
  5. 网站防盗链的配置部署,防止图片、视频等文件的白嫖、盗用。

3. Rewrite跳转的实现



rewrite使用Nginx全局变量或自己设置的变量,结合正则表达式和标志位实现URL重写以及重定向

4. Rewrite的实际场景

  1. nginx跳转需求的实现方式

    使用rewrite进行匹配跳转

    使用if匹配全局变量后跳转

    使用location匹配再跳转
  2. rewrite放在server{}、if{}、location{}段中

    location只对域名后边的除去传递参数外的字符串起作用
  3. 对域名或参数字符串

    使用if全局变量匹配

    使用proxy_pass反向代理

5. Rewrite和local的区别

从功能看rewrite和location似乎有点像,都能实现跳转。

主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,还可以proxy——pass到其他机器。

6. 常用的Nginx正则表达式

正则表达式 说明
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或多次
+ 匹配前面的字符一次或多次
? 匹配前面的字符零次或一次
. 匹配除"\n"之外的任何单个字符,若要匹配包括"\n"在内的任意字符,可使用"[.\n]"
/ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如"\n"匹配一个换行符,而“$”则匹配“$”
\d 匹配纯数字
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
[] 定义匹配的字符范围
[c] 匹配a-z小写字母的任意一个
[a-z] 匹配a-z小写字母的任意一个
[a-zA-Z0-9] 匹配所有大小写字母或数字
() 表达式的开始和结束位置
| 或运算符

7. Rewrite的执行顺序

  1. 执行server块里面的rewrite指令。
  2. 执行location匹配。
  3. 执行选定的location中的rewrite指令。

8. Rewrite的语法格式

rewrite [flag];

regex:表示正则匹配规则。

replacement:表示跳转后的内容。

flag:表示rewrite支持的flag标记。

9. flag的标记说明

falg标记 说明
last 本条规则匹配完成后,继续向下匹配新的location URL规则,一般用在server和if中。
break 本条规则匹配完成即终止,不再匹配后面的任何规则,一般使用在location中
redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

10. Rewrite示例

  1. 基于域名的跳转

    测试场景:现在公司旧域名www.old.com有业务需求变更,需要使用新域名www.new.com,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

    server {
listen 80;
server_name www.old.com;
#修改域名
charset utf-8;
access_log /var/log/nginx/old.access.log;
#修改日志保存路径 location / {
#添加域名重定向
if($host = 'www.old.com') {
#$host为rewrite全局变量,代表请求主机头字段或主机名
rewrite ^/(.*)$ http://www.new.com/$1 permanent;
#$1为正则匹配的内容,即“域名/”之后的字符串
}
root html;
index index.html index.htm;
}
} [root@localhost ~]# echo "192.168.122.10 www.old.com www.new.com" >> /etc/hosts
[root@localhost ~]# systemctl restart nginx

测试:浏览器输入模拟访问http://www.old.com/test/1.html(虽然这个请求内容是不存在的)会跳转到www.new.com/test/1.html,查看元素可以看到返回301,实现了永久重定向跳转,而且域名后的参数也正常跳转。

  1. 基于客户端IP访问跳转

    测试场景:今天公司业务新版本上线,要求所有IP访问任务内容都显示一个固定维护页面,只有公司IP:192.168.122.10访问正常。
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

    server {
listen 80;
server_name www.test.com;
#修改域名
charset utf-8;
access_log /var/log/nginx/test.access.log;
#修改日志保存路径 #设置是否合法的IP标记
set $rewrite true;
#设置变量$rewrite,变量值为boole值ture
#判断是否为合法IP
if ($remote_addr ="192.168.122.10") {
set $rewrite false;
#当客户端为192.168.122.10时,将变量值设为false,不进行重写
} #除了合法IP,其他都是非法IP,进行重写跳转维护页面
if ($rewrite = true) {
#当变量值为true时,进行重写
rewrite (.+) /weihu.html;
#将域名后边的路径重写成/weihu.html,例如www.test.com/weihu.html
} location = /weihu/html {
root /var/www/html;
#网页返回/var/www/html/weihu.html的内容
} location / {
root html;
index index.html index.htm;
}
} [root@localhost ~]# mkdir -p /var/www/html/
[root@localhost ~]# echo "<h1>We are maintaining now,please wait!</h1>" > /var/www/html/weihu.html
[root@localhost ~]# systemctl restart nginx

测试:只有IP为192.168.122.10能正常访问,其他地址都是维护页面

注:如果rewrite (.+) /weihu.html;改成rewrite (.+) /weihu.html permanent;的话如果是非192.168.122.10的主机访问会使浏览器修改请求访问的URL成http://www.test.com/weihu.html再请求访问,这样就会进入一直在rewrite的死循环,访问请求会一直重写成http://www.test.com/weihu.html再请求访问。

  1. 基于旧域名跳转到新域名后面加目录

    测试场景:现在访问的是http://bbs.test.com/post/,现在需要将这个域名下面的访问都跳转到http://www.test.com/bbs/post/
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

server {
listen 80;
server_name bbs.test.com;
#修改域名
charset utf-8;
#添加
location /post {
rewrite (.+) http://www.test.com/bbs$1 permanent;
#这里的$1为位置变量,代表/post
} location / {
root html;
index index.html index.htm;
}
} [root@localhost ~]# mkdir -p /usr/local/nginx/html/bbs/post
[root@localhost ~]# echo "this is 1.html" >> /usr/local/nginx/html/bbs/post/1.html
[root@localhost ~]# echo "192.168.80.10 bbs.test.com" >> /etc/hosts
[root@localhost ~]# systemctl restart nginx

测试:使用浏览器访问http://bbs.test.com/post/1.html跳转到http://www.test.com/bbs/post/1.html

  1. 基于参数匹配的跳转

    测试场景:现在访问http://www.test.com/100-(100|200)-100.html跳转到http://www.test.com页面。
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

server {
listen 80;
server_name www.test.com;
#修改域名
charset utf-8;
access_log /var/log/nginx/www.test.com-access.log; if ($request_uri ~ ^/100-(100-200)-(\d+).html$) {
rewrite (.+) http://www.test.com permanent;
} location / {
root html;
index index.html index.htm;
}
} [root@localhost ~]# systemctl restart nginx

$request_uri:包含请求参照的原因URI,不包含主机名,如:http://www.test.com/abc/bbs/index.html?a=1&b=2中的/abc/bbs/index.php?a=1&b=2

$uri:这个变量指当前的请求URI,不包括任何参数,如:/abc/bbs/index.html

$document_uri:与$uri相同,这个变量指当前的请求URI,不包含任务传递参数,如:/abc/bbs/index.html

测试:使用浏览器访问http://www.test.com/100-200-100.html或http://www.test.com/100-100-100.html跳转到http://www.test.com页面。

  1. 基于目录下所有php结尾的文件跳转

    测试场景:要求访问http://www.test.com/upload/123.php
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

server {
listen 80;
server_name www.test.com;
#修改域名
charset utf-8;
access_log /var/log/nginx/www.test.com-access.log; location ~* /upload/.*\.php$ {
rewrite (.+) http://www.test.com permanent;
} location / {
root html;
index index.html index.htm;
}
} [root@localhost ~]# systemctl restart nginx

测试:浏览器访问http://www.test.com/upload/123.php跳转到http://www.test.com页面。

  1. 基于最普通一条url请求的跳转

    要求访问一个具体的页面如http://www.test.com/abc/123.html跳转到首页
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

    listen       80;
server_name www.test.com;
#修改域名
charset utf-8;
access_log /var/log/nginx/www.test.com-access.log; location / {
root html;
index index.html index.htm;
}
} [root@localhost ~]# systemctl restart nginx

浏览器访问http://www.test.com/abc/123.html跳转到http://www.test.com页面。

Nginx中的Location和Rewrite的更多相关文章

  1. Nginx中的 location 匹配和 rewrite 重写跳转

    Nginx中的location匹配和rewrite重写跳转 1.常用的Nginx正则表达式 2.location 3.rewrite 4.rewrite实例 1.常用的Nginx正则表达式: ^ :匹 ...

  2. NGINX中的proxy_pass和rewrite

    文章作者:luxianghao 文章来源:http://www.cnblogs.com/luxianghao/p/6807081.html 转载请注明,谢谢合作. 免责声明:文章内容仅代表个人观点,如 ...

  3. 转:NGINX中的proxy_pass和rewrite

    章作者:luxianghao 文章来源:http://www.cnblogs.com/luxianghao/p/6807081.html 转载请注明,谢谢合作. 免责声明:文章内容仅代表个人观点,如有 ...

  4. 干货 | 一文彻底读懂nginx中的location指令

    一个执着于技术的公众号 Nginx系列导读 给小白的 Nginx 10分钟入门指南 Nginx编译安装及常用命令 完全卸载nginx的详细步骤 Nginx 配置文件详解 一文带你读懂Nginx反向代理 ...

  5. nginx中的location匹配规则

    概述: 1. location在nginx配置文件中的作用是根据用户请求的URI来执行不同的应用. 2.URI的定义:标识.定位任何资源的字符串 协议://域名/目录a/目录b/文件c http:// ...

  6. nginx中使用srcache_nginx模块构建缓存

    nginx中可以将lua嵌,让nginx执行lua脚本,可以处理高并发,非阻塞的处理各种请求,openresty项目中可以使用nignx可以直接构建 srcache_nginx + redis 缓存, ...

  7. nginx中location、rewrite用法总结

    一.location用法总结 location可以把不同方式的请求,定位到不同的处理方式上. 1.location的用法 location ~* /js/.*/\.js 以 = 开头,表示精确匹配:如 ...

  8. Nginx中location匹配及rewrite重写

    目录 一.常用的Nginx正则表达式 二.location 2.1.location三类匹配类型 2.2.常用的匹配规则 2.3.location优先级 2.3.1.举例说明 2.4.实际网站使用中, ...

  9. Nginx教程(四) Location配置与ReWrite语法

    Nginx教程(四) Location配置与ReWrite语法 1 Location语法规则 1.1 Location规则 语法规则: location [=|~|~*|^~] /uri/ {- } ...

随机推荐

  1. JdbcTemplate 基本使用

    简介 JdbcTemplate 是 Spring 对 JDBC 的封装,目的是使 JDBC 更加易于使用.JdbcTemplate 是 Spring 的一部分.JdbcTemplate 处理了资源的建 ...

  2. js 将数字型 的字符串 转 数字 【整数 /浮点型数字】

    1. js 提供了两种可以将 数字型 的字符串 转 数字 的方法 parseInt()和parseFloat(), parseInt() 是转成整数, 但 向下去整数 , parseFloat() 是 ...

  3. 一个高性能跨平台基于Python的Waitress WSGI Server的介绍!

    对于Python来说,它有很多web框架,常见的有jango.Flask.Tornado .sanic等,比如Odoo.Superset都基于Flask框架进行开发的开源平台,具有强大的功能.在Lin ...

  4. hyperf 如何对AMQP消息进行手动消费?

    转发自白狼栈:查看原文 在使用 hyperf 官方自带的 AMQP 队列时你会发现,不需要我们再额外启动进程对消息进行消费.这是因为默认情况下,使用 @Consumer 注解时,hyperf 会为我们 ...

  5. 带你自定义实现Spring事件驱动模型

    Spring 事件驱动模型概念 Spring 事件驱动模型就是观察者模式很经典的一个应用,我们可以通过Spring 事件驱动模型来完成代码的解耦. 三角色 Spring 事件驱动模型或者说观察者模式需 ...

  6. http://dl-ssl.google.com/android上不去解决方案

    转:https://blog.csdn.net/j04110414/article/details/44149653/ 一. 更新sdk,遇到了更新下载失败问题: Fetching https://d ...

  7. ASCII、Unicode和UTF-8等常见字符编码格式介绍

    信息存储在计算机中是转换成二进制来存储的,二进制的发明据说是来源于中国阴阳八卦.后德国数理哲学大师莱布尼茨是最早接触中华文化的欧洲人之一,从他的传教士朋友鲍威特寄给他的拉丁文译本<易经>中 ...

  8. AVD模拟器怎么配置上网

    转自:http://blog.csdn.net/you_jinjin/article/details/7228303 方法一 首先,Windows下,配置Adroid环境变量(Win7为例) 1.桌面 ...

  9. 【刷题-LeetCode】211. Add and Search Word - Data structure design

    Add and Search Word - Data structure design Design a data structure that supports the following two ...

  10. prometheus+exporter小测试:

    1.golang中使用expoter import ( "github.com/prometheus/client_golang/prometheus/promhttp" ) fu ...