`
风过无声
  • 浏览: 93027 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Nginx 变量漫谈(三)内置变量 被索引&未索引 (转载)

 
阅读更多

转载自 http://blog.sina.com.cn/openresty

 

也有一些内建变量是支持改写的,其中一个例子是 $args. 这个变量在读取时返回当前请求的 URL 参数串(即请求 URL 中问号后面的部分,如果有的话 ),而在赋值时可以直接修改参数串。我们来看一个例子:

    location /test {

        set $orig_args $args;

        set $args "a=3&b=4";

 

        echo "original args: $orig_args";

        echo "args: $args";

    }

这里我们把原始的 URL 参数串先保存在 $orig_args 变量中,然后通过改写 $args 变量来修改当前的 URL 参数串,最后我们用 echo 指令分别输出 $orig_args 和 $args 变量的值。接下来我们这样来测试这个 /test 接口:

    $ curl 'http://localhost:8080/test'

    original args: 

    args: a=3&b=4

 

    $ curl 'http://localhost:8080/test?a=0&b=1&c=2'

    original args: a=0&b=1&c=2

    args: a=3&b=4

在第一次测试中,我们没有设置任何 URL 参数串,所以输出 $orig_args 变量的值时便得到空。而在第一次和第二次测试中,无论我们是否提供 URL 参数串,参数串都会在 location /test 中被强行改写成 a=3&b=4.

 

    需要特别指出的是,这里的 $args 变量和 $arg_XXX 一样,也不再使用属于自己的存放值的容器。当我们读取 $args 时,Nginx 会执行一小段代码,从 Nginx 核心中专门存放当前 URL 参数串的位置去读取数据;而当我们改写 $args 时,Nginx 会执行另一小段代码,对相同位置进行改写。Nginx 的其他部分在需要当前 URL 参数串的时候,都会从那个位置去读数据,所以我们对 $args 的修改会影响到所有部分的功能。我们来看一个例子:

    location /test {

        set $orig_a $arg_a;

        set $args "a=5";

        echo "original a: $orig_a";

        echo "a: $arg_a";

    }

这里我们先把内建变量 $arg_a 的值,即原始请求的 URL 参数 a 的值,保存在用户变量 $orig_a 中,然后通过对内建变量 $args 进行赋值,把当前请求的参数串改写为 a=5 ,最后再用 echo 指令分别输出 $orig_a 和 $arg_a 变量的值。因为对内建变量 $args 的修改会直接导致当前请求的 URL 参数串发生变化,因此内建变量 $arg_XXX 自然也会随之变化。测试的结果证实了这一点:

    $ curl 'http://localhost:8080/test?a=3'

    original a: 3

    a: 5

我们看到,因为原始请求的 URL 参数串是 a=3, 所以 $arg_a 最初的值为 3, 但随后通过改写 $args 变量,将 URL 参数串又强行修改为 a=5, 所以最终 $arg_a 的值又自动变为了 5.

 

    我们再来看一个通过修改 $args 变量影响标准的 HTTP 代理模块 ngx_proxy 的例子:

    server {

        listen 8080;

 

        location /test {

            set $args "foo=1&bar=2";

            proxy_pass http://127.0.0.1:8081/args;

        }

    }

 

    server {

        listen 8081;

 

        location /args {

            echo "args: $args";

        }

    }

这里我们在 http 配置块中定义了两个虚拟主机。第一个虚拟主机监听 8080 端口,其 /test 接口自己通过改写 $args 变量,将当前请求的 URL 参数串无条件地修改为 foo=1&bar=2. 然后 /test 接口再通过 ngx_proxy 模块的 proxy_pass 指令配置了一个反向代理,指向本机的 8081 端口上的 HTTP 服务 /args. 默认情况下,ngx_proxy 模块在转发 HTTP 请求到远方 HTTP 服务的时候,会自动把当前请求的 URL 参数串也转发到远方。

 

    而本机的 8081 端口上的 HTTP 服务正是由我们定义的第二个虚拟主机来提供的。我们在第二个虚拟主机的 location /args 中利用 echo 指令输出当前请求的 URL 参数串,以检查 /test 接口通过 ngx_proxy 模块实际转发过来的 URL 请求参数串。

 

    我们来实际访问一下第一个虚拟主机的 /test 接口:

    $ curl 'http://localhost:8080/test?blah=7'

    args: foo=1&bar=2

我们看到,虽然请求自己提供了 URL 参数串 blah=7,但在 location /test 中,参数串被强行改写成了 foo=1&bar=2. 接着经由 proxy_pass 指令将我们被改写掉的参数串转发给了第二个虚拟主机上配置的 /args 接口,然后再把 /args 接口的 URL 参数串输出。事实证明,我们对 $args 变量的赋值操作,也成功影响到了 ngx_proxy 模块的行为。

 

    在读取变量时执行的这段特殊代码,在 Nginx 中被称为“取处理程序”(get handler);而改写变量时执行的这段特殊代码,则被称为“存处理程序”(set handler)。不同的 Nginx 模块一般会为它们的变量准备不同的“存取处理程序”,从而让这些变量的行为充满魔法。

 

    其实这种技巧在计算世界并不鲜见。比如在面向对象编程中,类的设计者一般不会把类的成员变量直接暴露给类的用户,而是另行提供两个方法(method),分别用于该成员变量的读操作和写操作,这两个方法常常被称为“存取器”(accessor)。下面是 C++ 语言中的一个例子:

    #include <string>

    using namespace std;

 

    class Person {

    public:

        const string get_name() {

            return m_name;

        }

 

        void set_name(const string name) {

            m_name = name;

        }

 

    private:

        string m_name;

    };

在这个名叫 Person 的 C++ 类中,我们提供了 get_name 和 set_name 这两个公共方法,以作为私有成员变量 m_name 的“存取器”。

 

    这样设计的好处是显而易见的。类的设计者可以在“存取器”中执行任意代码,以实现所需的业务逻辑以及“副作用”,比如自动更新与当前成员变量存在依赖关系的其他成员变量,抑或是直接修改某个与当前对象相关联的数据库表中的对应字段。而对于后一种情况,也许“存取器”所对应的成员变量压根就不存在,或者即使存在,也顶多扮演着数据缓存的角色,以缓解被代理数据库的访问压力。

 

    与面向对象编程中的“存取器”概念相对应,Nginx 变量也是支持绑定“存取处理程序”的。Nginx 模块在创建变量时,可以选择是否为变量分配存放值的容器,以及是否自己提供与读写操作相对应的“存取处理程序”。

 

    不是所有的 Nginx 变量都拥有存放值的容器。拥有值容器的变量在 Nginx 核心中被称为“被索引的”(indexed);反之,则被称为“未索引的”(non-indexed)。

 

分享到:
评论

相关推荐

    章亦春nginx漫谈

    Nginx 提供了多种内置变量,同时支持自定义变量。内置变量通常用于获取特定的信息,例如请求头、请求 URI 等;自定义变量则允许用户根据需要创建和设置。 **内置变量示例**: - `$request_uri`:表示请求的 URI。 -...

    nginx内置变量

    **Nginx内置变量概述** Nginx是一个高性能的HTTP和反向代理服务器,它具有模块化设计和出色的并发处理能力。在Nginx配置中,内置变量扮演着至关重要的角色,它们允许管理员动态地获取关于请求、客户端、服务器状态...

    Nginx内置变量列表

    nginx内置变量列表,根据 Nginx 源码文件 ngx_http_variables.c 提取了nginx 的内置变量。

    nginx自定义变量与内置预定义变量的使用

    这些内置变量极大地扩展了Nginx配置的灵活性,允许开发者根据HTTP请求的具体情况做出相应的响应。 综上所述,Nginx的自定义变量和内置预定义变量提供了强大的配置能力,使Nginx成为了一个高度可定制的Web服务器和...

    nginx 内置变量详解及隔离进行简单的拦截

    1,nginx内置变量 nginx 有很多内置变量可以进行简单的过滤。 $arg_name 请求行中的name参数。 $args 请求行中参数字符串。 $cookie_name 名为name的cookie。 与$uri相同。 $http_name 任意请求头的值;变量名的后...

    Nginx 内置预变量都有哪些?

    Nginx 内置预变量都有哪些?

    NGINX conf 配置文件中的变量大全

    在深入探讨NGINX配置文件中的变量之前,我们先简要了解一下NGINX。NGINX是一款高性能的HTTP和反向代理服务器,广泛应用于互联网上处理高并发连接、静态文件服务以及负载均衡等场景。其配置文件是实现NGINX功能的核心...

    nginx 内置变量表 Excel版.rar

    经常需要配置Nginx ,其中有许多以 $ 开头的变量,经常需要查阅nginx 所支持的变量。 可能是对 Ngixn资源不熟悉,干脆就直接读源码,分析出支持的变量。 Nginx支持的http变量实现在 ngx_http_variables.c 的 ngx_...

    linux-autoindexforNginx美化Nginx默认的目录文件索引页

    `autoindex`模块是Nginx的一个内置功能,允许我们自定义和美化目录索引页面。在标题和描述中提到的"Linux-autoindex for Nginx美化Nginx默认的目录文件索引页",就是指如何通过配置Nginx来实现这一目标。 首先,...

    Nginx-Index索引页面

    **Nginx-Index索引页面** 在Nginx服务器配置中,`index`指令用于定义默认的索引页面,当用户访问一个目录时,如果该目录下存在这个指定的索引文件,Nginx会自动加载并显示该页面,而无需用户手动输入文件名。这极大...

    agentzh 的 Nginx 教程(版本 2016.07.21)整理成pdf 添加书签

    - **内置变量与自定义变量**:比较内置变量与用户自定义变量的区别。 - **变量与HTTP请求处理**:探讨变量如何参与HTTP请求的处理流程。 - **变量与安全性**:分析变量使用不当可能带来的安全风险。 #### Nginx ...

    Nginx经典教程

    #### 一、Nginx变量漫谈 Nginx的变量系统是其灵活性和强大功能的核心之一。代理zh的《Nginx经典教程》深入探讨了Nginx变量的各个方面,从基础概念到高级应用,提供了全面的讲解。 1. **变量类型**:介绍了Nginx...

    分享最新版 nginx内置变量 大全

    nginx内置变量 内置变量存放在 ngx_http_core_module 模块中,变量的命名方式和apache 服务器变量是一致的。总而言之,这些变量代表着客户端请求头的内容,例如$http_user_agent, $http_cookie, 等等。下面是nginx...

    agentzh写的Nginx教程

    2. Nginx教程的内容计划:教程将按照系列的方式组织,每个系列会涵盖一个主题,比如"Nginx变量"系列,这些系列可以被视为将来可能出版的Nginx书籍的章节。 3. 文章的风格:教程采用了较为随性的风格,旨在向广大...

    Nginx教程.pdf

    5. **变量与函数**:某些Nginx模块还提供了内置函数来处理变量,例如`map`指令可以用来转换变量值。 #### 二、Nginx配置指令的执行顺序 1. **配置结构**:Nginx的配置文件是由一系列嵌套的块构成的,每个块可以...

    nginx全局变量整理小结

    Nginx 全局变量整理小结 Nginx 全局变量是 Nginx 服务器中的一组预定义变量,用于存储当前请求的信息和服务器的状态。这些变量可以在 Nginx 配置文件中使用,帮助管理员更好地管理和优化服务器。这篇文章将对 Nginx...

    window下nginx配置

    ### Window下Nginx配置详解 #### 一、前言 一直以来,许多开发者都认为Nginx只能在Linux环境下运行,实际上,在Windows系统中同样可以部署并高效运行Nginx。随着网站流量的增长,单台服务器可能无法满足需求,此时...

    nginx访问日志通用索引模板

    nginx访问日志通用索引模板,直接导入elasticsearch即可

Global site tag (gtag.js) - Google Analytics