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. Nginx 添加防爬虫

    include agent_deny.conf; conf下添加 #禁止Scrapy|curl等工具的抓取 if ($http_user_agent ~* (Scrapy|Curl|HttpClien ...

  2. 第10组 Beta冲刺 (3/5)(组长)

    1.1基本情况 ·队名:今晚不睡觉 ·组长博客:https://www.cnblogs.com/cpandbb/p/14018630.html ·作业博客:https://edu.cnblogs.co ...

  3. Mysql查询阻塞的sql

    SELECTp2.`HOST` 被阻塞方host,p2.`USER` 被阻塞方用户,r.trx_id 被阻塞方事务id,r.trx_mysql_thread_id 被阻塞方线程号,TIMESTAMPD ...

  4. uniapp 判断 IOS和Android的GPS是否开启并设置启动

    checkOpenGPSServiceByAndroidIOS() { let system = uni.getSystemInfoSync(); // 获取系统信息 console.log(syst ...

  5. 大厂面试来了,欢聚时代四年多经验的Java面经

    前言(也就是废话) 今年年底,额,不对,应该说是去年了,我开始进行了一个多月的面试之旅. 面试的公司并不多,但从体量上来看,基本算是一二三线的大厂都囊括了,其中还包括BAT,当然,最后我也是顺利的拿到 ...

  6. Maven插件开发教程

    Maven是一个一个优秀的项目管理开源框架,其插件机制为其功能扩展提供了非常大的便捷性.大多数情况下,我们不需要自己开发Maven插件,因为Maven本身提供了很多便捷的官方插件.但是对于某些特殊场景 ...

  7. 自动化集成:Pipeline整合Docker+K8S

    前言:该系列文章,围绕持续集成:Jenkins+Docker+K8S相关组件,实现自动化管理源码编译.打包.镜像构建.部署等操作:本篇文章主要描述流水线集成K8S用法. 一.背景描述 分布式服务的部署 ...

  8. c++智能指针的使用,shared_ptr,unique_ptr,weak_ptr

    c++智能指针的使用 官方参考 普通指针的烦恼:内存泄漏,多次释放,提前释放 智能指针 负责自动释放所指向的对象. 三种智能指针 shared_ptr,unique_ptr,weak_ptr: 将sh ...

  9. 彻彻底底地理解TCP三次握手和四次挥手的全部过程

    三次握手 我们先提出一些问题,但是我们暂且不回答这些问题,下面我会尽我所能详尽地讲解TCP的三次握手过程,然后看完你可以在评论区留下你对问题的答案,我们可以一起探讨. 为什么要握手 为什么是三次而不是 ...

  10. TensorRT 开始

    TensorRT 是 NVIDIA 自家的高性能推理库,其 Getting Started 列出了各资料入口,如下: 本文基于当前的 TensorRT 8.2 版本,将一步步介绍从安装,直到加速推理自 ...