NGINX的rewrite模块

4.18 Rewrite 模块

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perlcompatible regular expression),因此编译之前要安装PCRE库.

rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,另外还可以在一定程度上提高网站的安全性。

比如: 利用rewrite 模块可以实现下面网站URL的跳转

http://www.58.com/bj --> http://beijing.58.com

4.18.1ngx_http_rewrite_module 模块指令

官方文档: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

4.18.1.1 if 指令

用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:

if (条件匹配) {
action
}

使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:

注:$http_name

任意请求标头字段,变量名称的最后一部分是转换为小写的字段名称,用下划线替换短划线;

= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!=  #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false#官方示例
if ($http_user_agent ~ MSIE) {rewrite ^(.*)$ /msie/$1 break;
}id=123?name=wang
取出123
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {set $id $1;
}if ($request_method = POST) {return 405;
}请求的方法if ($slow) {limit_rate 10k;
}限速if ($invalid_referer) {return 403;
}盗链
server{listen 443 ssl;server_name www.ehuo.org;ssl_certificate /apps/nginx/conf.d/ssl/www.ehuo.org.pem ;ssl_certificate_key /apps/nginx/conf.d/ssl/www.ehuo.org.key ;root /data/nginx/html/pc ;location /main { index index.html;default_type text/html;if ( $scheme = http ){echo "if------>  $scheme";}if ( $scheme = https){  echo "if --->  $scheme";}}
}   

可以通过主机头来连接,就不用配置DNS

curl -H"host: www.ehuo.org" http://10.0.0.68/

走的是https

4.18.1.2 set 指令

指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key
value,value可以是text, variables和两者的组合。

erver{listen 443 ssl;server_name www.ehuo.org;ssl_certificate /apps/nginx/conf.d/ssl/www.ehuo.org.pem ;ssl_certificate_key /apps/nginx/conf.d/ssl/www.ehuo.org.key ;root /data/nginx/html/pc ;default_type text/html; location /main { index index.html;if ( $scheme = http ){                                                                        echo "if------>  $scheme";}if ( $scheme = https){  echo "if --->  $scheme";}}    location /test {set $name ehuo ;echo $name ;set $my_port $server_port;echo $my_port ;}}

范例:根据网络判断是否限速

server {
.....
location /set {set $slow 1; #如果为0,则不限速,非0限速if ($slow) {limit_rate 10k;}}
}
4.18.1.3 break 指令

用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位
于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器
在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在
server块和locationif块中使用

注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模
块的指令,其它指令还会执行

 location /break {set $name ehuo ;echo $name ;break ;  #location块中break后面指令还会执行set $my_port $server_port ;echo $my_port ; echo $name ;}

4.18.1.4 return 指令

return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊
重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所
有配置都将不被执行,return可以在server、if 和 location块进行配置

语法格式:

return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code URL; #返回给客户端的URL地址
return URL; #302跳转返回给客户端的URL地址,注意:URL必须是完整的URL包括scheme,如http://www.magedu.org/

范例:

拒绝特定的浏览器

location  /return {if ($http_user_agent  ~* curl|wget|ApacheBench){return 666 "user_agent";}}#测试
[root@centos ~]# curl -A 'curl' www.ehuo.org/return/index.html -I
HTTP/1.1 200 OK
Server: nginx/1.22.0
Date: Thu, 09 Jun 2022 10:01:46 GMT
Content-Type: text/html
Content-Length: 27
Last-Modified: Thu, 09 Jun 2022 09:58:37 GMT
Connection: keep-alive
ETag: "62a1c44d-1b"
Accept-Ranges: bytes
root@centos ~]# curl -A 'chrome' www.ehuo.org/return/
data/nginx/html/pc/return#跳转到百度
location  /return {if ( $http_user_agent  ~* curl|wget|ApacheBench|chrome|firefox){return 301 http://www.baidu.com/;}}

http跳转到https

#方法1
server {listen 80;server_name www.ehuo.org;return 302 https://$server_name$request_uri; #跳转到本链接
}
server {listen 443 ssl http2;server_name www.ehuo.org;ssl_certificate  /etc/nginx/ssl/www.ehuo.org.crt;ssl_certificate_key /etc/nginx/ssl/www.ehuo.org.key;location / {root /data/www/html;}
}#方法2
server {listen 80 ;listen 443 ssl;ssl_certificate /apps/nginx/ssl/www.wang.org.crt;ssl_certificate_key /apps/nginx/ssl/www.wang.org.key;ssl_session_cache shared:sslcache:20m;ssl_session_timeout 10m;server_name www.wang.org ;root /data/nginx/html/pc;if ($scheme = http) {return https://www.wang.org/;}location = /nginx_status {stub_status;}
}

4.18.2 rewrite 指令

通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,
rewrite主要是针对用户请求的URL或者是URI做具体处理

rewrite可以配置在 server、location、if

rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI

注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制

如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301

4.18.2.1 rewrite flag 使用介绍

利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时
重定向302)、permanent(永久重定向301)、break和last。

其中前两种是跳转型的flag,后两种是代理型。

  • 跳转型指由客户端浏览器重新对新地址进行请求,客户端的浏览器地址信息会发生变化,如:301,302

  • 代理型是在WEB服务器内部实现跳转,客户端的浏览器地址信息不会发生变化,如: last,break

Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。

Default: —

Context: server, location, if

flag说明

redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;
使用相对路径,或者http://或https://开头,状态码:302permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用
#适用于一个URL一次重写last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户

无标记用法:

[root@centos8 ~]#cat /apps/nginx/conf.d/www.ehuo.org.conf
server {listen 80;server_name www.ehuo.org;root /data/site;location / {rewrite /1.html /2.html;rewrite /2.html /3.html;}location /2.html {rewrite /2.html /a.html;}location /3.html {rewrite /3.html /b.html;}
}#准备对应代码
[root@centos8 ~]#mkdir -p /data/site
[root@centos8 ~]# echo "1.html" >/data/site/1.html
[root@centos8 ~]# echo "2.html" >/data/site/2.html
[root@centos8 ~]# echo "3.html" >/data/site/3.html
[root@centos8 ~]# echo "a.html" >/data/site/a.html
[root@centos8 ~]# echo "b.html" >/data/site/b.html#测试结果: 当请求http://www.ehuo.org/1.html,最终将会访问/b.html过程:/---->/1---->/2----->/3----->/3------>/b.html
4.18.2.2 break 与 last
4.18.2.2.1 break 案例
[root@centos8 ~]#cat /apps/nginx/conf.d/www.ehuo.org.conf
server {listen 80;server_name www.ehuo.org;root /data/site;location / {rewrite /1.html /2.html break;rewrite /2.html /3.html;}location /2.html {rewrite /2.html /a.html;}location /3.html {rewrite /3.html /b.html;}
}

测试结果: 当请求/1.html,最终会访问/2.html

**原因:在location{}内部,遇到break,本location{}内以及后面的所有location{}内的所有指令都不再执行。

4.18.2.2.2 last 案例

last:对某个location的URL匹配成功后,会停止当前location的后续rewrite规则,并结束当前location,
然后将匹配生成的新URL跳转至其他location继续匹配,直到没有location可匹配后, 将最后一次location的数据返回给客户端。

last 适用于要不改变客户端访问方式但是需做多次目的URL重写的场景

root@centos8 ~]#cat /apps/nginx/conf.d/www.ehuo.org.conf
server {listen 80;server_name www.ehuo.org;root /data/site;location / {rewrite /1.html /2.html last;rewrite /2.html /3.html;}location /2.html {rewrite /2.html /a.html;}location /3.html {rewrite /3.html /b.html;}
}

测试结果:当请求/1.html,最终会访问/a.html

原因:在location{}内部,遇到last,本location{}内后续指令不在执行;

而重写后的url会对所在的server{…}标签重新发起请求,从头到尾匹配一遍规则,哪个匹配则执行哪个。

4.18.2.2.3 break 和 last 区别
  • rewrite指令中的break和last都属于服务器内部跳转,客户端链接地址不变,客户端无感知

  • 当rewrite规则遇到break指令后,本location{}后续的指令与其他location{}的所有指令都不执行。

  • 当rewrite规则遇到last指令后,本location{}里后续规则不执行,但重写后的url会再次从头开始匹配所有Location,也包括本location,哪个location先匹配到就执行哪个,可能会造成死循环500错误

4.18.2.3 永久与临时重定向

域名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳
转,这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。

示例: 因业务需要,将访问源域名 www.ehuo.org 的请求永久重定向到 www.huoyi.com

location / {root /data/nginx/html/pc;index index.html;rewrite / http://www.huoyi.com permanent;#rewrite / http://www.huoyi.com redirect;
}
#重启Nginx并访问域名 http://www.ehuo.org 进行测试
4.18.2.3.1 永久重定向301

域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到
客户端浏览器

永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也会利用缓存进行重定向

比如: 京东早期的域名 www.360buy.com 由于与360公司类似,于是后期永久重定向到了 www.jd.com

范例: permanent 301永久重定向

[root@centos8 ~]#cat /apps/nginx/conf.d/www.ehuo.org.conf
server {listen 80;server_name www.ehuo.com;root /data/site;location / {rewrite /1.html /2.html permanent;rewrite /2.html /3.html;}
}
#测试结果: 当请求/1.html,最终会访问/2.html
#原因:在location{}内部遇到permanent,客户端会重新发起新请求到新的重定向地址进行访问,而且url
会修改为后面的新URL
4.18.2.3.2 临时重定向302

域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器
不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久重定向最大的本质区别。

即当nginx服务器无法访问时,浏览器不能利用缓存,而导致重定向失败

范例: redirect 302 临时重定向

[root@centos8 ~]#cat /apps/nginx/conf.d/www.ehuo.org.conf
server {listen 80;server_name www.ehuo.com;root /data/site;location / {rewrite /1.html /2.html redirect ;rewrite /2.html /3.html;}
}#测试结果: 当请求/1.html,最终会访问/2.html
#原因:在location{}内部遇到redirect,客户端会重新发起新请求到新的重定向地址进行访问,而且url会
修改为后面的新URL
4.18.2.3.3 redirect与permanent区别

redirect与permanent都会导致客户端上重新发起的请求,链接地址会发生变化,客户端可以感知到变化

NGINX的rewrite模块相关推荐

  1. Nginx的rewrite模块疑问排查

    标题索引 追溯原因 实验分析 原理总结 追踪原因 最近心态"一步一印,有印为证",在Nginx的rewrite模块在工作过程中,客户端发起包到服务器解包整体过程浏览器做了什么?服务 ...

  2. centos 7.6——Nginx中rewrite模块应用(location)——基于域名的跳转等

    centos 7.6--Nginx中rewrite模块应用(location)--基于域名的跳转等 文章目录 centos 7.6--Nginx中rewrite模块应用(location)--基于域名 ...

  3. nginx 的 rewrite 模块

    ngxhttprewrite_module 模块用来使用正则表达式(PCRE)改变请求的 URI,返回重定向,并有条件地选择配置. 指令执行顺序 首先顺序执行 server 块中的 rewrite 模 ...

  4. nginx安装rewrite模块

    Linux nginx安装目录找不到? 如果找不到,那应该就是没有完成安装或者编译: 首先要确认是否正确安装了: make&&makeinstall重新编译一次 其次,在确定安装的目录 ...

  5. 实例演示Nginx重写(Rewrite)类型last、break、redirect和permanent的区别

    本文使用之前制作的Docker容器<<Docker案例:搭建nginx服务>>演示Nginx四种重写类型的区别和效果,如果尚未构建Docker服务可参考之前的文章,或者自建Ng ...

  6. nginx(三十二)rewrite模块

    一    官方rewrite模块 1)这个模块作用于'SERVER_REWRITE'和'REWRITE'阶段,前者的优先级'较高'2)根据rewrite模块出现在'server{}'还是'locati ...

  7. Nginx极客时间:rewrite阶段的rewrite模块:return指令

    1. rewrite模块的return指令: return指令 是由 rewrite模块提供的 一个非常常用的指令,可以在 SERVER_REWRITE 和 REWRITE 这两个阶段生效, 它可以帮 ...

  8. 1. nginx扩展——ngx_lua 模块简介、安装

    1. 简介 ​ lua-nginx-module(ngx_lua module)把 Lua5.1 的解释器 或 LuaJIT 2.0/2.1 的解释器嵌入到 nginx 中,将强大的 Lua 线程(L ...

  9. Nginx源码研究之nginx限流模块详解

    这篇文章主要介绍了Nginx源码研究之nginx限流模块详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 高并发系统有三把利器:缓存.降级和限流: 限流的目的是通过对并 ...

最新文章

  1. JavaScript精简代码 非一般的写法(转载)
  2. java堆与非堆的一些研究_堆和堆傻傻分不清?一文告诉你 Java 集合中「堆」的最佳打开方式...
  3. apple air装双系统(win7)
  4. servlet和webservice+WEBservice 的本质。
  5. GDCM:gdcm::UUIDGenerator的测试程序
  6. solver.prototxt参数说明(三)
  7. csrf保护php,防止PHP中的CSRF
  8. 如何在 Apache 中为你的网站设置404页面
  9. ActionScript 3.0 Step By Step系列(四):来自面向对象开发之前的呐喊:“学会写可重用的代码”...
  10. idea中 Java xml注释缩进问题 解决方案
  11. 超好用的网页浮动广告代码
  12. 【推荐】区块链技术及行业应用资料合集
  13. 第六章-博弈论之Stackelberg博弈
  14. HTML文本域添加滑杆,Objective-C 自定义UISlider滑杆 分段样式
  15. Mybaits-Plus Invalid bound statement (not found) 问题
  16. 视频的帧率和分辨率以及码率的关系
  17. 微信小程序数据拼接_最佳方式实现微信小程序分页加载数据
  18. 多线程并发数量设置设多少算合理
  19. 阿里巴巴Java开发手册摘要(一)
  20. 解决:Required request body is missing

热门文章

  1. 苹果MacBook选购指南,Macbook Air和Pro如何选?
  2. 从n开始学习python语言(一)
  3. 高精度尘埃粒子计数器工厂空气质量监测必备
  4. 用户画像准确性评测初探 ——拨开python大数据分析的神秘面纱
  5. 小白之AuthorizeAttribute权限控制(一)
  6. 毕业设计之 --- 目标检测-行人车辆检测流量计数
  7. 怎么恢复未保存的word文件
  8. 【苹果相册推送iMessage】群发公用推送服务器(APNS)
  9. 三分钟教你读懂支票是什么
  10. java我的世界基本技巧,2022最新