Linux Nginx 变量——概念、定义变量、echo模块、作用域、内置变量用途

Nginx 变量
Nginx的配置文件使用语法是一门微型的编程语言,可以像写编写配置文件,可操作性较大。

1、Nginx变量简介
所有的 Nginx变量在配置文件中引用时都须带上 $ 前缀:

在 Nginx 配置中,变量只能存放一种类型的值,有且只有一种类型,那就是字符串类型;
nginx可以使用变量简化配置与提高配置的灵活性:

用法:

$变量名

2、Nginx 变量的定义和使用

Nginx的变量分为:自定义变量与内置预定义变量

  • 自定义变量

声明变量可以在sever,http,location等标签中使用set命令(非唯一)声明变量

语法:

set $变量名 变量值

PS.
nginx 中的变量都以$开头

nginx 的配置文件中所有使用的变量都必须是声明过的,否则 nginx 会无法启动并打印相关异常日志

  • 变量的可见性

在不同层级的标签中声明的变量性的可见性不同:
location中声明的变量中对这个location块可见
server中声明的变量对server块以及server块中的所有子块可见
http中声明的变量对http块以及http块中的所有子块可见

nginx安装echo模块

查看已经安装的nginx的版本
[root@192 ~]# nginx -V 
下载echo模块的安装包
[root@192 ~]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz
[root@192 ~]# ls
anaconda-ks.cfg  nginx-1.16.0.tar.gz  v0.61.tar.gz
解压到相同路径下:
[root@192 ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/
[root@192 ~]# tar xzf v0.61.tar.gz -C /usr/local/
安装编译工具
[root@192 ~]# cd /usr/local/
[root@192 local]# yum -y install pcre pcre-devel openssl openssl-devel gcc gcc-c++   zlib zlib-devel
添加模块:
[root@192 local]# cd nginx-1.16.0/
添加上原来已经有的参数和新添加的模块:
[root@192 nginx-1.16.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/usr/local/echo-nginx-module-0.61
[root@192 nginx-1.16.0]# make   #编译,不要make install 否则会覆盖原来的文件
[root@192 nginx-1.16.0]#  mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_bak2 #将原来的nignx备份
[root@192 nginx-1.16.0]# cp objs/nginx /usr/local/nginx/sbin/  拷贝nignx
[root@192 nginx-1.16.0]# /usr/local/nginx/sbin/nginx  #启动
[root@192 nginx-1.16.0]# nginx -V  查看模块是否添加成功

3、配置 $foo=hello

[root@192 ~]# cd /etc/nginx/conf.d/
[root@192 conf.d]# vim echo.conf
server {
        listen 80;
        server_name     localhost;
        location /test {
                set $foo hello;
                echo "foo: $foo";
        }
}

输出

[root@192 conf.d]# nginx -s reload
[root@192 conf.d]# curl localhost/test
foo: hello

使用大括号插值
在“变量插值”的上下文中,当引用的变量名之后紧跟着变量名的构成字符时(比如后跟字母、数字以及下划线),需要使用特别的记法来消除歧义

如:

server {
        listen 80;
        server_name     localhost;
        location /test-brace {
                set $first "hello ";
                echo "${first}world";
        }
}
或者
server {
        listen 80;
        server_name     localhost;
        location /test-brace {
                set $first "hello";
                echo "$first world";
        }
}

输出

[root@192 conf.d]# nginx -s reload 
[root@192 conf.d]# curl localhost/test-brace
hello world

在 echo 配置指令的参数值中引用变量 first 的时候,后面紧跟着 world ,所以如果直接写作 “firstworld” 则 Nginx “变量插值”计算引擎会将之识别为引用了变量 firstworld. 为了解决这个问题,Nginx 的字符串记法支持使用花括号在 之后把变量名围起来,比如这里的 ${first}。

4、变量作用域
set 指令不仅有赋值的功能,它还有创建 Nginx 变量的作用,即当作为赋值对象的变量尚不存在时,它会自动创建该变量。如果不创建就直接使用它的值,则会报错。

server {
    ...
    location /bad {
        echo $foo;
    }
}

此时 Nginx 服务器会拒绝加载配置:

[root@192 conf.d]# nginx -s reload 
nginx: [emerg] unknown "foo" variable
nginx: configuration file /etc/nginx/nginx.conf test failed

Nginx 变量的创建和赋值操作发生在全然不同的时间阶段,Nginx 变量的创建只能发生在 Nginx 配置加载的时候,即 Nginx 启动的时候,而赋值操作则只会发生在请求实际处理的时候。
不创建而直接使用变量会导致启动失败,同时无法在请求处理时动态地创建新的 Nginx 变量。
Nginx 变量一旦创建,其变量名的可见范围就是整个 Nginx 配置,甚至可以跨越不同虚拟主机的 server 配置块。

如:

server {
        listen 80;
        server_name     localhost;
        location /foo {
                echo "foo = [$foo]";
        }
        location /bar {
                set $foo 32;
                echo "foo = [$foo]";
        }
}

输出

[root@192 conf.d]# curl 'http://localhost/foo'
foo = []
[root@192 conf.d]# curl 'http://localhost/bar'
foo = [32]

在 location /bar 中用 set 指令创建了变量 foo,于是在整个配置文件中这个变量都是可见的,因此可以在 location /foo 中直接引用这个变量而不用担心 Nginx 会报错。

从例子可以看到,set 指令因为是在 location /bar 中使用的,所以赋值操作只会在访问 /bar 的请求中执行。而请求 /foo 接口时,总是得到空的 foo值,因为用户变量未赋值就输出的话,得到的便是空字符串。

从例子可以窥见一个重要特性是,Nginx 变量名的可见范围虽然是整个配置,但每个请求都有所有变量的独立副本,或者说都有各变量用来存放值的容器的独立副本,彼此互不干扰。比如前面求了 /bar 接口后,foo 变量被赋予了值 32,但它丝毫不会影响后续对 /foo 接口的请求所对应的 foo 值(它仍然是空的!),因为各个请求都有自己独立的 $foo 变量的副本。

  • 内置预定义变量

内置预定义变量即无需声明就可以使用的变量,通常包括一个http请求或响应中一部分内容的值,以下为一些常用的内置预定义变量

在这里插入图片描述

Nginx 内置变量获取关于请求或响应各种信息。

1、uri vs request_uri
由 ngx_http_core 模块提供的内建变量 uri,可以用来获取当前请求的 URI(不含请求参数),
而 request_uri 则用来获取请求最原始的 URI(包含请求参数)。

server {
        listen 80;
        server_name     localhost;
        location /test-uri {
                echo "uri = $uri";
                echo "request_uri = $request_uri";
        }
}

输出

[root@192 conf.d]# nginx -s reload 
[root@192 conf.d]# curl localhost/test-uri
uri = /test-uri
request_uri = /test-uri
[root@192 conf.d]# curl "localhost/test-uri?a=3&b=4"
uri = /test-uri
request_uri = /test-uri?a=3&b=4
[root@192 conf.d]# curl "localhost/test-uri/hello%20world?a=3&b=4"
uri = /test-uri/hello world
request_uri = /test-uri/hello%20world?a=3&b=4

2、$arg_XXX
另一个特别常用的内建变量[并不是单独一个变量],而是有无限多变种的一群变量,即名字以 arg_ 开头的所有变量,称之为 arg_XXX 变量群。
例: arg_name,这个变量的值是当前请求中名为 name 的参数的值,而且还是未解码的原始形式的值。

server {
        listen 80;
        server_name     localhost;
        location /test-arg {
        echo "name: $arg_name";
        echo "class: $arg_class";
        }
}

输出

[root@192 conf.d]# nginx -s reload
[root@192 conf.d]# curl localhost/test-arg
name: 
class: 
​
[root@192 conf.d]# curl "localhost/test-arg?name=Tom&class=3"
name: Tom
class: 3
​
[root@192 conf.d]# curl "localhost/test-arg?name=hello%20world&class=9"
name: hello%20world
class: 9

3、$arg_XXX 不区分大小写
其实 $arg_name 不仅可以匹配 name 参数,也可以匹配 NAME 参数,抑或是 Name,Nginx 会在匹配参数名之前,自动把原始请求中的参数名调整为全部小写的形式。

[root@192 conf.d]# curl "localhost/test-arg?NAME=Marry"
name: Marry
class: 
[root@192 conf.d]# curl "localhost/test-arg?Name=Jimmy&class=DSfef"
name: Jimmy
class: DSfef
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值