当前位置:首页 > 技术 > 正文内容

Nginx rewrite 详解

Lotus2022-12-08 13:29技术

Nginx rewrite 详解

本篇主要介绍 nginx 的 rewrite 重定向这个功能进行 详解介绍, 以及介绍它的使用场景

image-20221202113505079

1. rewrite 基本介绍

rewrite是实现URL重写的关键指令,根据regex (正则表达式)部分内容,重定向到replacement,结尾是flag标记。

基本语法:

rewrite 	<regex> 	<replacement> 	[flag];
关键字 		正则 				替代内容 			flag标记
  • regex: 正则表达式语句进行规则匹配
  • replacement: 将正则匹配的内容替换成replacement
  • flag: last | break | redirect | permanent
    • last : 本条规则匹配完成后,继续向下匹配新的location URI规则
    • break: 本条规则匹配完成即终止,不再匹配后面的任何规则
    • redirect : 回302临时重定向,浏览器地址会显示跳转后的URL地址 (防爬虫)
    • permanent : 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

rewrite 使用位置

  • server : 在server中针对所有的请求
  • location : 在 location 中则针对 单个匹配路径的
  • If

2. server 中使用 rewrite

直接在server中使用 rewrite , 它会被先执行 优先于 location 中的

2.1 rewrite 外部站点

rewrite 到外部站点 是指 replacement 部分 是一个完整的 带 http/https 的 外部路径 ,它的特点是 浏览器会再次请求这个新的站点 所以浏览器上的地址一定会发生变化 不受 flag 参数影响

全部拦截 ^/(.*)$

下面的配置是 所有的请求都转发了 https://www.askajohnny.com

...
server {
        listen       80;
        server_name  www.testfront.com;
        #由于是外部站点带http/s 的 所以不受flag 影响  break last .. 都会进行跳转并且变更浏览器url
        rewrite ^/(.*)$ https://www.askajohnny.com break;

        location / {
            root html;
            index index.html;
        }
}
...

部分匹配

server {
        listen       80;
        server_name  www.testfront.com;
        #只有当后缀是 数字.html 的时候才会转发到  https://www.askajohnny.com
        rewrite ^/([0-9]+).html$ https://www.askajohnny.com break;
        #其他的请求会走到这个location中
        location / {
            root html;
            index index.html;
        }
}

经过测试可以发现 直接跳转过去 并且 浏览器中的地址也直接变成了 https://www.askajohnny.com , 待会我们再详细讨论 什么时候会变化这个地址

比如在我的 博客网站中 我把http 的请求全部rewrite 转发到 https 上了, 因为我的QQ登录当时填写的回调是 http,又因为QQ互联的审核太麻烦 太慢 所以干脆就这样配置

image-20221202110932520

2.2 rewrite 到内部站

rewrite 到内部站点是指 replacement 不带http/https 而是内部的另外一个路径 , 相当于访问隐藏起来的这个 内部路径, 只有这种内部站点跳转的时候 浏览器才有可能不变地址 要看 rewite flag 参数了 last 和 break 都不会变的, 只有 redirect 和 permanent

server {
        listen       80;
        server_name  www.testfront.com;
        #只有当后缀是 数字.html 的时候才会转发到  https://www.askajohnny.com
        rewrite ^/([0-9]+).html$ /my.gif break;
        #其他的请求会走到这个location中
        location / {
            root html;
            index index.html;
        }
        # 上面的rewrite 会被路由到这里 并且浏览器是不会感知到的 
        location /my.gif {
            root /www/static/;
        }
}

经过测试 当访问 www.testfront.com/222.html 的时候

  • flag = last 浏览器不会变化 隐藏了 后端 /my.gif 地址
  • flag = break 浏览器不会变化 隐藏了 后端 /my.gif 地址
  • flag = redirect 和 permanent 浏览器变化了URL 变更状态码 302和 301

3. location 中使用rewrite

location 中也可以使用 rewrite 意思是只有匹配到 这个location 后才经过 rewrite 的正则通过后 再跳转

和上面一样 也分为 rewirte 的 replacement 是否包含http和https 外部站点

希望是如果 访问的后缀 是 数字.html 则 返回 my.gif 图 ,其他的都代理到 http://www.testbackend.com

server {
        listen       80;
        server_name  www.testfront.com;

        #rewrite ^/([0-9]+).html$ /my.gif last;

        location /my.gif {
	   			root /www/static/;
				}

        location / {
            rewrite ^/([0-9]+).html$ /my.gif break;
            proxy_pass http://www.testbackend.com;
        }
 }

经过测试 只有访问www.testfront.com/数字.html 的时候 才能获取到 my.gif 文件

4. 使用场景模拟

4.1 基于域名跳转

比如现在你所在的公司 网站域名是 www.testfront.com 现在需要使用新的域名 www.newtestfront.com 替代, 但是旧的域名不能作废, 需要让旧的域名跳转到新的域名上 , 并且保持后面参数不变

模拟原本配置

server {
        listen       80;
        server_name  www.testfront.com;
        
        location / { 
            proxy_pass http://www.testbackend.com;
        }
 }

新配置,使用rewrite 操作 当访问老的域名 www.testfront.com 跳转到 新的 www.newtestfront.com

   server {
        listen       80;
        server_name  www.testfront.com ...;

        location / {
            # $host 是可以拿到访问的主机名
            if ( $host = 'www.testfront.com' ) {

                rewrite ^/(.*)$ http://www.newtestfront.com/$1 permanent;
            }

            proxy_pass http://www.testbackend.com;
        }

       location ^~ /static/ {
	    		root  /www/static;
			 }
    }

    server {
        listen       80;
        server_name  www.newtestfront.com;

        location / {
           # 这里可以改成 新域名的 新后端代理的服务, 依据实际情况
           proxy_pass http://www.testbackend.com;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
   }

4.2 基于客户端 IP 访问跳转

今天公司业务新版本上线,要求所有 IP 访问任何内容都显示一个固定维护页面,只有公司IP:192.168.200.100访问正常。

   server {
        listen       80;
        server_name  www.testfront.com ...;
        
        # 先设置 rewrite变量为true
        set $rewrite true;
         
        # 当客户端ip 是172.16.225.1 的时候 才不 rewrite
        if ( $remote_addr = "172.16.225.1" ) {
           set $rewrite = false;
        }
        
        if ( $rewirte = true) {
           # 将rewrite到 维护界面 weihu.html
           rewrite (.+) /weihu.html; 
        }
        
        location /weihu.html {
           # 如果要使用 echo 则需要加载 echo-nginx-module 才行
        	 echo "remote_addr: $remote_addr";
           root /www/weihu/;
        }

        location / {
         		# 如果要使用 echo 则需要加载 echo-nginx-module 才行
        		echo "remote_addr: $remote_addr";
            # 如果是 remote_addr 是特定的ip 则直接正常访问后台
            proxy_pass http://www.testbackend.com;
        }
    }

此时如果是 172.16.225.1 访问就可以到 后端, 如果是其他的客户端ip 访问就只能到 weihu.html 页面

image-20221202083339741

image-20221202083423353

注意 下面是 echo-nginx-module 模块需要单独下载加载 如果你需要调试的话

git clone https://gitee.com/yaowenqiang/echo-nginx-module.git

总结

本篇主要介绍了 nginx 中 rewrite 的基本概念 以及基本的使用方式 ,rewrite 可以出现在 server , location , if 中

并且介绍了 什么时候才会变化浏览器URL , 以及介绍了2个模拟场景

  • rewirte 内部站点

    当rewrite 到内部站点的时候 会根据 flag 参数 last break不变 redirect permanent 变化

  • rewrite 外部站点 带http/https 等

    当rewrite 外部站点 不管flag 参数 浏览器URL都会进行变化 相当于浏览器进行了 二次请求了

欢迎大家访问 个人博客 Johnny小屋
欢迎关注个人公众号

欢迎关注个人公众号

原文链接

扫描二维码推送至手机访问。

版权声明:本文来源于网络,仅供学习,如侵权请联系站长删除。

本文链接:https://news.layui.org.cn/post/1128.html

分享给朋友:

“Nginx rewrite 详解” 的相关文章

WinDbg Preview安装以及符号表配置

1、安装WinDbgPreview 在Microsoft Store直接搜索windbg就可以下载。 2、配置符号服务器 2.1 符号 符号是方便调试程序的文件,通常是pdb文件。一个模块(可执行程序,动态链接库)对应一个pdb文件。不同的windows版本中的文件不同(比如说kernel32),版本不同pdb符号文件也不同,因此要从微软提供的符号服务器获取本机对应的符号。 但是要在本地建立一个文...

用 VS Code 搞Qt6:使用 PySide 6

一般来说,用C++写 Qt 应用才是正宗的,不过,为了让小学生也能体验 Qt 的开发过程,或者官方为了增加开发者人数,推出了可用 Python 来编程的 Qt 版本。此版本命名比较奇葩,叫 PySide,与 Qt 6 配套的是 PySide 6。当前最新版本是 6.3.2。 PySide 的优势在于它是官方维护的,完全是C++开发的。在原有库基础上增加了对应的 .pyd 文件,对 API 做了封装...

[s905l3]性价比神机mgv3000全网首拆,刷armbian实现更多价值!

最近花55淘了一台mgv3000,s905l3,2+16G带蓝牙,真的性价比没得说 S905L3 工艺28nm差于s905l3a 主频1.9Ghz,超频可以达到2Ghz,GPU是Mail450,当服务器跑ha,nas什么都是很不错的。 而且还自带蓝牙,总体性价比比s905l3a系列高多了 按我的方法可以启动,网卡没有问题,但是目前没有显示,没有蓝牙。 等之后我有时间了照着安卓的dtb改一改也许会解...

Python基础(十) | Numpy详细教程

第十一章 Numpy库 ⭐本专栏旨在对Python的基础语法进行详解,精炼地总结语法中的重点,详解难点,面向零基础及入门的学习者,通过专栏的学习可以熟练掌握python编程,同时为后续的数据分析,机器学习及深度学习的代码能力打下坚实的基础。 ????本文已收录于Python基础系列专栏: Python基础系列教程 欢迎订阅,持续更新。 10.1 为什么要用Numpy 10.1.1  ...

CPS攻击案例(一)——基于脉冲宽度调制PWM的无人机攻击

​  本文系原创,转载请说明出处 Please Subscribe Wechat Official Account:信安科研人,获取更多的原创安全资讯 原论文链接:sec22-dayanikli.pdf (usenix.org) 目录 摘要 一 知识背景 1.1 CPS 1.2 脉冲宽度调制PWM 二 攻击方案研究思路 2.1 研究背景 2.2 灵感与动机 2.3 PWM控制执行器的机理 2.3....

JavaScript之无题之让人烦躁的模块化

  我怎么记得我好像写过相关类型的文章,但是我找遍了我的博客没有~那就再写一遍吧,其实模块化的核心内容也算不上是复杂,只不过需要整理一下,规划一下罢了。嘻嘻。   开始写标题的时候我就在纠结一件事情,就是,先吃喜欢吃的,还是后吃喜欢吃的,翻译过来就是我应该先写CommonJS和ES6 Module,还是先写CMD和AMD。嗯,我决定了,谁先做好了我就先吃谁。   其实模块化的缘由很简单,就一句话,...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。