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 ~]# lsanaconda-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.confserver {
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/testfoo: 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-bracehello 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-uriuri = /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-argname:
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