• nginx URL重写


    Nginx系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.html


    1.1 简介

    url重写由ngx_http_rewrite_module模块提供,默认会安装,但该模块功能的实现需要pcre。URL重写技术不仅要求掌握几个指令的语法、熟悉简单的正则表达式,还需要尽量熟悉nginx的各个变量的意义,熟悉的变量越多越好。大多数需要用到的变量都是http_core模块提供的,它们的意义参见官方手册http_core内置变量

    rewrite模块主要有break、return、set、rewrite和if这5个指令。

    • break的作用是完成当前的作用集,不再执行rewrite指令
    • return返回状态码。可用的状态码有204/301/302/303/307/308/400/402-406/408/410-411/413/416/500-504。return三种语法:
      return code [text];
      return code URL;
      return URL;
      
    • set用于定义变量。赋给变量的值可以是一个变量、文本及文本变量的组合(语法:set variable value;)
    • if用于设定判断条件。格式为if (condition) {}
    • rewrite用于设定URL重写规则(语法:rewrite regex replacement [flag];)

    1.2 if指令

    if不支持嵌套,不支持"&&"和"||"多目运算符。语法为:

    if (condition) {}
    

    测试条件可以如下定义:

    (1). 变量的比较可以使用"="和"!="运算符。
    (2). 正则匹配可以使用"~"和"~*",前者表示区分大小写的正则匹配,后者表示不区分大小写的匹配。
    (3). 正则匹配可以在前面加上感叹号"!~"和"!~*"表示取反,即不匹配。
    (4). "-f"和"!-f"判断文件是否存在。
    (5). "-d"和"!-d"判断目录是否存在。
    (6). "-e"和"!-e"判断文件或目录或软链接是否存在。
    (7). "-x"和"!-x"判断文件是否可执行。

    if支持的正则表达式可以使用$1至$9来实现反向引用。

    以下为几个示例:

    # 当使用IE浏览器访问时,重定向到/msie/目录下的对应文件
    if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /msie/$1 break;
    }
    
    # 当http请求的方法为POST,则直接返回405状态码,即Method not Allowed
    if ($request_method = POST) {
        return 405;
    }
    
    # 当请求的资源文件不存在,则直接退出当前匹配,并代理至本机,这种情况下由本机来提供服务,如提供错误页面
    if (!-f $request_filename) {
        break;
        proxy_pass http://127.0.0.1;
    }
    
    # 当访问的是longshuai.com下任意主机,则重定向到www.longshuai.com主机下的对应目录
    if ($http_host ~* "^(.*).longshuai.com$") {
        set $domain $1;
        rewrite ^(.*) http://www.longshuai.com/$domain/ break;
    }
    

    上面最后一种URL重写后的URL为一个新的主机名站点,但使用URL重写的效率比较低下,远不如直接为此站点独立定义一个虚拟主机。所以改写为:

    server {
        listen 80;
        server_name .longshuai.com;
        return 302 http://www.longshuai.com/$request_uri;
    }
    
    server {
        listen 80;
        server_name www.longshuai.com;
    }
    

    1.3 rewrite指令

    rewrite可以写在server段、location段和if段。语法:

    rewrite regexp replacement [flag]
    

    如果replacement部分以"http://"或"https://"或"$schema"开头,则直接临时重定向,见下表中的redirect标记。

    flag是标记。有4种标记,它们的作用如下表。

    flag说明
    last 停止处理当前上下文中的其他重写模块指令,并为重写后的uri再次进行上下文的匹配
    break 和last指令一样,都是停止处理当前上下文中的其他重写模块指令
    redirect 返回临时重定向状态码302。当replacement部分不是以"http://"或者"https://"或者"$schema"开头的时候使用,"$schema"变量表示使用的是什么协议
    permanent 返回永久重定向状态码301

    以上flag中,last和break用来实现URL改写,此时浏览器中的地址不会改变,但实际上在服务器上访问的资源和路径已经改变了。redirect和permanent用来实现URL跳转,浏览器中的地址会改变为跳转后的地址

    在使用proxy_pass指令时要使用break标记。last标记在本条rewrite规则执行完后,继续在当前上下文对重写后的地址发起匹配请求,而break则在本次匹配完成后停止再次匹配。例如下面的两条重写规则。

    rewrite "^/bbs/(.*)/images/(.*).jpg$" www.longshuai.com/bbs/$2/images/$1.jpg last;
    rewrite "^/bbs/(.*)/images/(.*).jpg$" www.longshuai.com/bbs/$2/images/$1.jpg break;
    

    如果访问的是www.longshuai.com/bbs/a/images/b.jpg则重写后为www.longshuai.com/bbs/b/images/a.jpg,但是重写后的地址仍然可以匹配到规则^/bbs/(.*)/images/(.*).jpg$,此时如果使用last标记,则会再次进行重写,最终导致URL重写循环,nginx默认支持10次循环,然后返回500状态码。而如果使用break标记,则在重写完成后不会再次匹配重写。

    例如,下面的重写示例将会使得任意以longshuai.com结尾的访问重定向到www.longshuai.com。

    server_name  www.longshuai.com;
    rewrite (.*).longshuai.com www.longshuai.com permanent;
    

    下面的重写实例将使得www.longshuai.com/bbs/*的访问都重定向到www.longshuai.com/forum/*。

    server {
        listen 80;
        server_name www.longshuai.com;
        location /{
            root /www/longshuai/;
            index index.html;
            rewrite "/bbs/(.*)" "/forum/$1" last;
        }
    }
    

    1.4 URL重写和反向代理的区别

    URL重写和反向代理都能将请求转发到其他主机上。但它们有很大的区别。

    1.URL重写可以实现一些反向代理不能实现的转发。
    2.URL重写可以实现浏览器地址改变。
    3.反向代理更多的配合upstream实现负载均衡。URL重写无法直接通过转发实现负载均衡。
    4.还有很多其他的区别,无需关心它们的区别,当某种需求既可以URL重写实现,也可以反向代理实现,随便用一种方法即可。

  • 相关阅读:
    Spring 整合Struts2 + hibernate
    回调机制
    Struts2配置RESULT中TYPE的参数说明
    hibernate:通用DAO+动态生成HQL语句
    java API chm html 1.5 1.6 中文版英文版 帮助文档
    generator class中各项值的作用及定义
    Hibernate 中 set 里的属性及定义
    一个人的前端项目,踩过的那些坑,一一道来。
    哪些个在 Sublime Text 下,"任性的" 好插件!
    深度挖掘,Html5的 Range 滑动刻度的坑,兼容全平台,将任性进行到底!
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/7685485.html
Copyright © 2020-2023  润新知