nginx location与rewrite

1,104 阅读4分钟

Nginx执行的过程

url = 域名+端口+path+param

匹配过程:

1、域名(ip)+端口 ----》定位虚拟机

2、path与location部分匹配,

​ path = 匹配path + 剩余path

3、root:在目录里找path1+path2路径

 alias:在目录里找path2路径

​ 若url以/结尾,认为是目录,执行index;否则认为path路径到达文件

4、 proxy_pass=http://172.17.0.4:8081/

proxy_pass= ip:port/

​ ip:port/时,转发ip+端口+path2路径

​ ip:port 时,转发ip+端口+path1+path2路径

例如:http://172.17.0.4:8081/nginx/enjoy/getInfo?a=1&b=2

image-20200628142549622

Location语法规则

符号 含义
= = 开头表示精确匹配
^~ ^~开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)
~ ~ 开头表示区分大小写的正则匹配
~* ~* 开头表示不区分大小写的正则匹配
!~和!~* !~和!~*分别为区分大小写不匹配及不区分大小写不匹配的正则
/ 用户所使用的代理(一般为浏览器)

如上表所示,location的语法规则为location [=|~|~*|^~] /uri/ {… },主要支持三种匹配方式

  • 精准匹配:=
  • 普通匹配:
    • 无前缀:/
    • ^~:不使用正则
  • 正则匹配
    • ~”表示区分大小写;
    • “~*”表示不区分大小写;

location的匹配流程如下:

image-20200628143145406

server {
  listen       80;
  server_name  location.enjoy.com;

  location /a {
          rewrite ^/  /a.html break;
          root   html/static/;
  }
  location /b/a {
          rewrite ^/  /b.html break;
          root   html/static/;
  }
  location /b/d/a {
          rewrite ^/  /d.html break;
          root   html/static/;
  }
  location ^~/b/c/a {
          rewrite ^/  /d.html break;
          root   html/static/;
  }
  location ~ /b/d {
          rewrite ^/  /c.html break;
          root   html/static/;
  }
  location ~ /b/d/a {
          rewrite ^/  /a.html break;
          root   html/static/;
  }
}

ReWrite的使用

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

rewrite只能放在server{},location{},if{}中,

并且只能对域名后边的除去传递的参数外的字符串起作用,

例如http://seanlook.com/a/we/index.jsp?id=1&u=str 只对/a/we/index.php重写。

语法rewrite regex replacement [flag];flag有5种修饰符

  • break

    #这个指令表示,如果/login匹配成功,则直接在home路径中查找demo.html文件
    #然后跳转到demo.html。注意这是内部跳转,浏览器上的地址url不会变,还是以/login结尾。
    location  /login {
           rewrite  ^/  /demo.html  break;
           root  home/;
    }
    
  • redirect(301重定向)

    #和break差不多,不过这个表示外部跳转,也会跳转到demo.html页面,不过浏览器地址会自动变成demo.html
    location  /login {
           rewrite  ^/  /demo.html  redirect;
           root  home/;
    }
    
  • permanent (302重定向) 和redirect作用类似

  • last

    #nginx会将/demo.html地址和其他location的地址进行匹配,然后找到匹配的地址,继续执行下去。这里他会执行到 /demo.html 的location中,然后内部跳转到/demo.html页面,如下
    location  /login {
           rewrite  ^/  /demo.html  last;
           root  home/;
    }
     
    location  /demo.html {
           rewrite  ^/  /demo.html  break;
           root  home/;
    }
    
  • 没有修饰符

    #没有修饰,就是无任何修饰。可以看到这个rewrite后面没有任何修饰。当没有任何修饰的情况下,匹配中location后,不会停止,会继续想下面的location继续匹配下去。直到匹配到最后一个,使用最后一个匹配到的。
    location  /login {
           rewrite  ^/  /demo.html ;
           root  home/;
    }
    

image-20200628144744258

location和rewrite进阶:

location和rewrite进阶:

nginx运行阶段: rewrite 阶段、access 阶段以及 content 阶段

不按代码顺序执行,是按阶段执行,顺序如下:

先执行命中的所有rewrite层指令(下面的set),再执行access,再执行content(下面的echo)

语法:

location = / {
  set $a 32;
  echo $a;
  
  set $a 64;
  echo $a;

}

输出的是64,因为echo是输出语句,属于content阶段最后执行

补充

root和alias区别

aliasroot指令的区别就是:

  • 1、root不会将location配置的路径去掉 也就是请求http://localhost/res/xxx,不会忽略localhost的配置,反而会加在root配置的路径后面,变成f:/res/res/xxx
  • 2、alias会将location配置的路径去掉

也就是请求http://localhost/res/xxx,会忽略localhost的配置,不会加在alias配置的路径后面,变成f:/res/xxxlocation/res/被忽略了。

index执行时机

url 以 /结尾时,如:location.enjoy.com/static/,指的是…

url 不是以 / 结尾,location.enjoy.com/static,认为它是…

if语句

if语句 --- nginx没有else,if语句常用的正则如下

= ,!= 比较的一个变量和字符串。
~, ~* 与正则表达式匹配的变量,如果这个正则表达式中包含
-f,!-f 检查一个文件是否存在。
-d, !-d 检查一个目录是否存在。
-e,!-e 检查一个文件、目录、符号链接是否存在。
-x, !-x 检查一个文件是否可执行。

nginx内置变量

  • $host:请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称

  • http_HEADER : HTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写,-变为_(破折号变为下划线),例如:http_user_agent(Uaer-Agent的值)

  • $remote_addr 客户端的IP地址。

  • $remote_port 客户端的端口。

  • $request_method 这个变量是客户端请求的动作,通常为GET或POST。

  • $request_uri 这个变量等于包含一些客户端请求参数的原始URI

  • $scheme 所用的协议,比如http或者是https

  • $server_name 服务器名称。

  • $server_port 请求到达服务器的端口号。

  • $server_protocol 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。

  • uri 请求中的当前URI(不带请求参数,参数位于args)