当前位置: 首页 > news >正文

nginx rewrite模块探究与实验

关于nginx中的rewrite,之前的理解总感觉有些不精确。比如以下问题,经过rewrite之后:

      什么情况会返回200?

      什么情况会返回301/302?

      什么情况浏览器里的url不变?

      什么情况浏览器里的url会变?

      什么情况匹配一次就不再匹配之后的规则或location?

      什么情况匹配到一条规则后,会以rewrite之后的url再到server段走一遍

如果读者能理解清楚以上问题,则说明对nginx的rewrite整体上已经有了全面的认识。

接下来我们针对以上问题,来通过试验逐一解答

实验环境:nginx 1.8

网站根目录:nginx/html

注:在http段或者server段添加rewrite_log on;并且设置error_log为notice级别,可以在error og里捕捉到rewrite的过程

一、先实验一个最简单的:http://172.16.25.162/ljk.html。该文件不在在html下,而在在html/wordpress下

server {

         listen        80;

         server_name  localhost;

         rewrite_log on;

         location / {

           root   /usr/local/nginx/html;

           index  index.shtml index.php index.html;

           if (!-e $request_filename) {

              rewrite ^/(.+\..+)$ /wordpress/$1;

           }

         }

观察nginx访问日志和错误日志

access_log:

"GET /ljk.html HTTP/1.1" 200

error_log:

*98 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html

*98 rewritten data: "/wordpress/ljk.html", args: "", client:172.16.25.3, server: localhost, request: "GET /ljk.html 

浏览器里的url没有改变,状态码返回200

wKiom1YuOxzDk9XkAABOt1rn9hs806.jpg

由此可见,如此配置实现了一个最简单的内部跳转。

二、再进一步,看一个两级的rewrite。将html/wordpress/下的ljk.html移到html/ljk/下,并且在location /wordpress 下配置重写规则

         location / {

            root   /usr/local/nginx/html;

           index  index.shtml index.php index.html;

           if (!-e $request_filename) {

              rewrite ^/(.+\..+)$ /wordpress/$1;

           }

         }

        location /wordpress  {

            if (!-e $request_filename) {

               rewrite ^/wordpress/(.+\..+)$ /ljk/$1;

            }

        }

access_log:

"GET /ljk.html HTTP/1.1" 200

error_log:可以看到两次匹配与重写的过程

*99 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html 

*99 rewritten data: "/wordpress/ljk.html", args: "", client:172.16.25.3, server: localhost, request: "GET /ljk.html 

*99 "^/wordpress/(.+\..+)$" matches "/wordpress/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html 

*99 rewritten data: "/ljk/ljk.html", args: "", client: 172.16.25.3, server: localhost, request: "GET /ljk.html

浏览器url依然不变

wKioL1YuLuGii2meAABOt1rn9hs667.jpg

以上两个实验对用户透明,用户通过返回码或者地址栏url均不可感知rewrite的存在,可以看做‘内部重定向’;那么什么时候会产生‘外部重定向’呢,现在先试试Permanent、redirect两个标志

三、重写规则后加上 permanent 标志

         location / {

           root   /usr/local/nginx/html;

           index  index.shtml index.php index.html;

           if (!-e $request_filename) {

              rewrite ^/(.+\..+)$ /wordpress/$1 permanent;

           }

         }

访问http://172.16.25.162/ljk.html

access_log:

GET /ljk.html HTTP/1.1" 301     返回301

GET /wordpress/ljk.html HTTP/1.1" 200

注意此处产生了两个请求

error_log:

*107 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html

       *107 rewritten redirect: "/wordpress/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html

浏览器地址栏变成了rewrite后的url

wKiom1YuL9Dx0oK1AABgIZXQw0U866.jpg

四、重写规则后加上 redirect 标志

         location / {

           root   /usr/local/nginx/html;

           index  index.shtml index.php index.html;

           if (!-e $request_filename) {

              rewrite ^/(.+\..+)$ /wordpress/$1 redirect;

           }

access_log:    两个请求

"GET /ljk.html?sds HTTP/1.1" 302    临时重定向302

"GET /wordpress/ljk.html HTTP/1.1" 200

error_log:

*108 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html

       *108 rewritten redirect: "/wordpress/ljk.html?sds", client: 172.16.25.3, server: localhost, request: "GET /ljk.ht         ml?sds

浏览器地址栏变成了rewrite后的url

wKioL1YuMCuRKeZnAABgIZXQw0U417.jpg

由三四得出结论:Permanent、redirect两个标志控制是否将重过程在用户端体现出来(即将重写后的url显示在客户端)同时返回301 or 302。

然后再试试last和break两个标志(需要两层及以上跳转来测试)

按照网上较为普遍的说法:

假如一个location里有多条rewrite规则,都是不在该location继续往下匹配,但是

last: 匹配完该条语句后得到的url,重新到server标签下走一遍

break:到此为止(直接以重写后的url在服务器寻找资源)

实验环境:删除html/wordpress下的ljk.html,将ljk.html放置在html/ljk/ljk.html,然后在server标签下配置location /wordpress 的rewrite规则

五、先来看下两次rewrite 规则不加标志的情况

         location / {

           root   /usr/local/nginx/html;

           index  index.shtml index.php index.html;

           if (!-e $request_filename) {

              rewrite ^/(.+\..+)$ /wordpress/$1;

           }

         }

        location /wordpress  {

            if (!-e $request_filename) {

               rewrite ^/wordpress/(.+\..+)$ /ljk/$1;

            }

        }

access_log: 

GET /ljk.html HTTP/1.1" 200

error_log:    经历两次匹配和重写

       *111 "^/(.+\..+)$" matches "/ljk.html",

       *111 rewritten data: "/wordpress/ljk.html", args: "",

*111 "^/wordpress/(.+\..+)$" matches "/wordpress/ljk.html",

*111 rewritten data: "/ljk/ljk.html", args: "",

浏览器地址栏url不变

六、实验break标志

         location / {

           root   /usr/local/nginx/html;

           index  index.shtml index.php index.html;

           if (!-e $request_filename) {

              rewrite ^/(.+\..+)$ /wordpress/$1 break;

           }

         }

        location /wordpress  {

            if (!-e $request_filename) {

               rewrite ^/wordpress/(.+\..+)$ /ljk/$1;

            }

        }

access_log:

    GET /ljk.html HTTP/1.1" 404

error_log: 

    *112 "^/(.+\..+)$" matches "/ljk.html",

    *112 rewritten data: "/wordpress/ljk.html", args: "",

    *112 open() "/usr/local/nginx/html/wordpress/ljk.html" failed (2: No such file or directory),

加了break,所以在重写成‘wordpress/ljk.html’就没有再走到location /wordpress

七、实验last标志

         location / {

           root   /usr/local/nginx/html;

           index  index.shtml index.php index.html;

           if (!-e $request_filename) {

              rewrite ^/(.+\..+)$ /wordpress/$1 last;

           }

         }

        location /wordpress  {

            if (!-e $request_filename) {

               rewrite ^/wordpress/(.+\..+)$ /ljk/$1;

            }

        }

访问http://172.16.25.162/ljk.html

access_log:

    GET /ljk.html HTTP/1.1" 200

error_log:

    *113 "^/(.+\..+)$" matches "/ljk.html",

    *113 rewritten data: "/wordpress/ljk.html", args: "",

    *113 "^/wordpress/(.+\..+)$" matches "/wordpress/ljk.html",

    *113 rewritten data: "/ljk/ljk.html", args: "",

由五六七可得出结论:

加break标志时,url一旦找到匹配额规则,就会停止继续匹配并以该rewrite后额url去服务器请求资源;

加last标志或者不加任何标志,其‘过程’和‘结果’一致,会以rewrite后的url再重新到server段下走一遍配置。

并且这两个标志都不会改变浏览器地址栏的url,且返回码亦为200或404等(即对用户透明)

八、涉及到域名重定向的实验

    server {

         listen        80;

         server_name  localhost;

         rewrite_log on;

         rewrite ^(.*)$ http://www.baidu.com;

}

若rewrite规则后不加标志或者加redircet标志,都会返回“GET / HTTP/1.1" 302”临时重定向

当rewrite规则后加permanent 标志,会返回“GET / HTTP/1.1" 301”永久重定向

希望这篇文章能对理解nginx的rewrite有一些帮助!

相关文章:

  • SpringMVC(六):Spring 整合quartz作业调度框架
  • ecshop中那些有意思的代码
  • 查看死锁原因 /data/anr/traces.txt
  • 如何删除 SQL Server 表中的重复行
  • Android 不通过USB数据线调试的方法
  • Android网络开发之OkHttp--基本用法GET
  • 查看Android应用包名package和入口activity名称
  • ueditor 最新版本【1.4.3.1】单独文件/图片上传处理方法
  • 【原创】sizeof运算符总结
  • Android客户端性能测试常见指标及测试方法--转载
  • composer 报错笔记
  • ubuntu集群下ssh配置总结
  • 使用css3属性,大部分浏览器要识别前缀
  • 暴搜 - Codeforces Round #327 (Div. 2) E. Three States
  • iOS中正确的截屏姿势
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • es6要点
  • React16时代,该用什么姿势写 React ?
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 复杂数据处理
  • 后端_ThinkPHP5
  • 基于遗传算法的优化问题求解
  • 前嗅ForeSpider教程:创建模板
  • 区块链分支循环
  • 驱动程序原理
  • 正则表达式小结
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • # Panda3d 碰撞检测系统介绍
  • #if和#ifdef区别
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #QT项目实战(天气预报)
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $.ajax,axios,fetch三种ajax请求的区别
  • (1)Android开发优化---------UI优化
  • (27)4.8 习题课
  • (done) 两个矩阵 “相似” 是什么意思?
  • (ros//EnvironmentVariables)ros环境变量
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (新)网络工程师考点串讲与真题详解
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (译) 函数式 JS #1:简介
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)LINQ之路
  • (转载)利用webkit抓取动态网页和链接
  • .Net 代码性能 - (1)
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .net2005怎么读string形的xml,不是xml文件。