nginx 變量

nginx 變量

Nginx 同 Apache 等其他 Web 服務(wù)器的配置記法不太相同排苍,Nginx的配置文件使用語法的就是一門微型的編程語言层释。可以類似寫程序一般編寫配置文件桨昙,可操作性很大扎拣。既然是編程語言,一般也就少不了“變量”這種東西稽鞭。

1鸟整、nginx變量簡介

所有的 Nginx變量在 Nginx 配置文件中引用時都須帶上 $ 前綴

在 Nginx 配置中,變量只能存放一種類型的值朦蕴,有且也只存在一種類型篮条,那就是字符串類型

nginx可以使用變量簡化配置與提高配置的靈活性,所有的變量值都可以通過這種方式引用:

$變量名

2梦重、nginx 變量的定義和使用

nginx中的變量分為兩種兑燥,自定義變量與內(nèi)置預(yù)定義變量

1、自定義變量

1琴拧、聲明變量可以在sever,http,location等標(biāo)簽中使用set命令(非唯一)聲明變量,語法如下

set$變量名 變量值

注意:

nginx 中的變量必須都以$開頭

nginx 的配置文件中所有使用的變量都必須是聲明過的嘱支,否則 nginx 會無法啟動并打印相關(guān)異常日志

2蚓胸、變量的可見性

在不同層級的標(biāo)簽中聲明的變量性的可見性規(guī)則如下:

location標(biāo)簽中聲明的變量中對這個location塊可見

server標(biāo)簽中聲明的變量對server塊以及server塊中的所有子塊可見

http標(biāo)簽中聲明的變量對http塊以及http塊中的所有子塊可見

nginx安裝echo模塊

查看已經(jīng)安裝的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/

添加上原來已經(jīng)有的參數(shù)和新添加的模塊:

[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? 查看模塊是否添加成功

nginx version: nginx/1.16.0

built bygcc4.8.520150623(Red Hat4.8.5-36) (GCC)

built with OpenSSL1.0.2k-fips26Jan2017

TLS SNI support enabled

configure arguments:--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

3除师、配置 $foo=hello

[root@192 ~]# cd /etc/nginx/conf.d/

[root@192 conf.d]# vim echo.conf

server {

listen80;

? ? ?? server_name ? ? localhost;

? ? ?? location /test {

set$foohello;

echo"foo: $foo";

? ? ?? }

}

輸出

[root@192 conf.d]# nginx -s reload

[root@192 conf.d]# curl localhost/test

foo: hello

5沛膳、 使用大括號插值

在“變量插值”的上下文中,還有一種特殊情況汛聚,即當(dāng)引用的變量名之后緊跟著變量名的構(gòu)成字符時(比如后跟字母锹安、數(shù)字以及下劃線),我們就需要使用特別的記法來消除歧義倚舀,例如:

server {

listen80;

? ? ?? 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 配置指令的參數(shù)值中引用變量 first 的時候,后面緊跟著 world 這個單詞痕貌,所以如果直接寫作 "firstworld" 則 Nginx “變量插值”計算引擎會將之識別為引用了變量 firstworld. 為了解決這個難題风罩,Nginx 的字符串記法支持使用花括號在? 之后把變量名圍起來,比如這里的 ${first}舵稠。

6超升、變量作用域

set 指令不僅有賦值的功能入宦,它還有創(chuàng)建 Nginx 變量的副作用,即當(dāng)作為賦值對象的變量尚不存在時室琢,它會自動創(chuàng)建該變量乾闰。比如在上面這個例子中,如果 $a 這個變量尚未創(chuàng)建盈滴,則 set 指令會自動創(chuàng)建 $a 這個用戶變量涯肩。如果我們不創(chuàng)建就直接使用它的值,則會報錯雹熬。 例如

server {

?? ...

?? location /bad {

echo$foo;

?? }

}

此時 Nginx 服務(wù)器會拒絕加載配置:

[root@192 conf.d]# nginx -s reload

nginx: [emerg] unknown"foo"variable

nginx: configuration file /etc/nginx/nginx.conf test failed

Nginx 變量的創(chuàng)建和賦值操作發(fā)生在全然不同的時間階段宽菜,Nginx 變量的創(chuàng)建只能發(fā)生在 Nginx 配置加載的時候,或者說 Nginx 啟動的時候竿报,而賦值操作則只會發(fā)生在請求實際處理的時候铅乡。 這意味著不創(chuàng)建而直接使用變量會導(dǎo)致啟動失敗,同時也意味著我們無法在請求處理時動態(tài)地創(chuàng)建新的 Nginx 變量烈菌。

Nginx 變量一旦創(chuàng)建阵幸,其變量名的可見范圍就是整個 Nginx 配置,甚至可以跨越不同虛擬主機(jī)的 server 配置塊芽世。我們來看一個例子:

server {

listen80;

? ? ?? server_name ? ? localhost;

? ? ?? location /foo {

echo"foo = [$foo]";

? ? ?? }

? ? ?? location /bar {

set$foo32;

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 指令創(chuàng)建了變量 foo挚赊,于是在整個配置文件中這個變量都是可見的,因此我們可以在 location /foo 中直接引用這個變量而不用擔(dān)心 Nginx 會報錯济瓢。 從這個例子我們可以看到荠割,set 指令因為是在 location /bar 中使用的,所以賦值操作只會在訪問 /bar 的請求中執(zhí)行旺矾。而請求 /foo 接口時蔑鹦,我們總是得到空的 foo值,因為用戶變量未賦值就輸出的話箕宙,得到的便是空字符串嚎朽。

從這個例子我們可以窺見的另一個重要特性是,Nginx 變量名的可見范圍雖然是整個配置柬帕,但每個請求都有所有變量的獨立副本哟忍,或者說都有各變量用來存放值的容器的獨立副本,彼此互不干擾陷寝。比如前面我們請求了 /bar 接口后锅很,foo 變量被賦予了值 32,但它絲毫不會影響后續(xù)對 /foo 接口的請求所對應(yīng)的 foo 值(它仍然是空的E翁)粗蔚,因為各個請求都有自己獨立的 $foo 變量的副本。

2饶火、內(nèi)置預(yù)定義變量

內(nèi)置預(yù)定義變量即無需聲明就可以使用的變量鹏控,通常包括一個http請求或響應(yīng)中一部分內(nèi)容的值致扯,以下為一些常用的內(nèi)置預(yù)定義變量

變量名定義

$arg_PARAMETERGET請求中變量名PARAMETER參數(shù)的值。

$args這個變量等于GET請求中的參數(shù)当辐。例如抖僵,foo=123&bar=blahblah;這個變量只可以被修改

$binary_remote_addr二進(jìn)制碼形式的客戶端地址。

$body_bytes_sent傳送頁面的字節(jié)數(shù)

$content_length請求頭中的Content-length字段缘揪。

$content_type請求頭中的Content-Type字段耍群。

$cookie_COOKIEcookie COOKIE的值。

$document_root當(dāng)前請求在root指令中指定的值。

$document_uri與$uri相同。

$host請求中的主機(jī)頭(Host)字段丈咐,如果請求中的主機(jī)頭不可用或者空,則為處理請求的server名稱(處理請求的server的server_name指令的值)曹抬。值為小寫,不包含端口急鳄。

$hostname機(jī)器名使用 gethostname系統(tǒng)調(diào)用的值

$http_HEADERHTTP請求頭中的內(nèi)容谤民,HEADER為HTTP請求中的內(nèi)容轉(zhuǎn)為小寫,-變?yōu)開(破折號變?yōu)橄聞澗€)疾宏,例如:$http_user_agent(Uaer-Agent的值);

$sent_http_HEADERHTTP響應(yīng)頭中的內(nèi)容张足,HEADER為HTTP響應(yīng)中的內(nèi)容轉(zhuǎn)為小寫,-變?yōu)開(破折號變?yōu)橄聞澗€)坎藐,例如: $sent_http_cache_control, $sent_http_content_type…;

$is_args如果$args設(shè)置为牍,值為"?",否則為""岩馍。

$limit_rate這個變量可以限制連接速率吵聪。

$nginx_version當(dāng)前運行的nginx版本號。

$query_string與$args相同兼雄。

$remote_addr客戶端的IP地址。

$remote_port客戶端的端口帽蝶。

$remote_user已經(jīng)經(jīng)過Auth Basic Module驗證的用戶名赦肋。

$request_filename當(dāng)前連接請求的文件路徑,由root或alias指令與URI請求生成励稳。

$request_body這個變量(0.7.58+)包含請求的主要信息佃乘。在使用proxy_pass或fastcgi_pass指令的location中比較有意義。

$request_body_file客戶端請求主體信息的臨時文件名驹尼。

$request_completion如果請求成功趣避,設(shè)為"OK";如果請求未完成或者不是一系列請求中最后一部分則設(shè)為空新翎。

$request_method這個變量是客戶端請求的動作程帕,通常為GET或POST住练。包括0.8.20及之前的版本中,這個變量總為main request中的動作愁拭,如果當(dāng)前請求是一個子請求讲逛,并不使用這個當(dāng)前請求的動作。

$request_uri這個變量等于包含一些客戶端請求參數(shù)的原始URI岭埠,它無法修改盏混,請查看$uri更改或重寫URI。

$scheme所用的協(xié)議惜论,比如http或者是https许赃,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;

$server_addr服務(wù)器地址,在完成一次系統(tǒng)調(diào)用后可以確定這個值馆类,如果要繞開系統(tǒng)調(diào)用混聊,則必須在listen中指定地址并且使用bind參數(shù)。

$server_name服務(wù)器名稱蹦掐。

$server_port請求到達(dá)服務(wù)器的端口號技羔。

$server_protocol請求使用的協(xié)議,通常是HTTP/1.0或HTTP/1.1卧抗。

$uri請求中的當(dāng)前URI(不帶請求參數(shù)藤滥,參數(shù)位于args,不同于瀏覽器傳遞的args)社裆,不同于瀏覽器傳遞的request_uri的值拙绊,它可以通過內(nèi)部重定向,或者使用index指令進(jìn)行修改泳秀。不包括協(xié)議和主機(jī)名标沪,例如/foo/bar.html

Nginx 內(nèi)置變量最常見的用途就是獲取關(guān)于請求或響應(yīng)的各種信息。

1嗜傅、uri? vs request_uri

由 ngx_http_core 模塊提供的內(nèi)建變量 uri金句,可以用來獲取當(dāng)前請求的 URI(不含請求參數(shù)),而 request_uri 則用來獲取請求最原始的 URI(包含請求參數(shù))吕嘀。

server {

? ? ?? listen 80;

? ? ?? server_name ? ? localhost;

? ? ?? location /test-uri {

? ? ? ? ? ? ?? echo "uri = $uri";

? ? ? ? ? ? ?? echo "request_uri = $request_uri";

? ? ?? }

}

輸出

[root@localhost html]# nginx -s reload

[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

另一個特別常用的內(nèi)建變量其實并不是單獨一個變量,而是有無限多變種的一群變量偶房,即名字以 arg_ 開頭的所有變量趁曼,我們估且稱之為 arg_XXX 變量群。 一個例子是 arg_name棕洋,這個變量的值是當(dāng)前請求中名為 name 的參數(shù)的值挡闰,而且還是未解碼的原始形式的值。

server {

listen80;

? ? ?? 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 不區(qū)分大小寫

其實 $arg_name 不僅可以匹配 name 參數(shù)摄悯,也可以匹配 NAME 參數(shù)赞季,抑或是 Name,Nginx 會在匹配參數(shù)名之前射众,自動把原始請求中的參數(shù)名調(diào)整為全部小寫的形式碟摆。

[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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叨橱,隨后出現(xiàn)的幾起案子典蜕,更是在濱河造成了極大的恐慌,老刑警劉巖罗洗,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愉舔,死亡現(xiàn)場離奇詭異,居然都是意外死亡伙菜,警方通過查閱死者的電腦和手機(jī)轩缤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贩绕,“玉大人火的,你說我怎么就攤上這事∈缜悖” “怎么了馏鹤?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長娇哆。 經(jīng)常有香客問我湃累,道長,這世上最難降的妖魔是什么碍讨? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任治力,我火速辦了婚禮,結(jié)果婚禮上勃黍,老公的妹妹穿的比我還像新娘宵统。我一直安慰自己,他們只是感情好覆获,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布榜田。 她就那樣靜靜地躺著,像睡著了一般锻梳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上净捅,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天疑枯,我揣著相機(jī)與錄音,去河邊找鬼蛔六。 笑死荆永,一個胖子當(dāng)著我的面吹牛废亭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播具钥,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼豆村,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了骂删?” 一聲冷哼從身側(cè)響起掌动,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宁玫,沒想到半個月后粗恢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡欧瘪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年眷射,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佛掖。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡妖碉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芥被,到底是詐尸還是另有隱情欧宜,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布撕彤,位于F島的核電站鱼鸠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏羹铅。R本人自食惡果不足惜蚀狰,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望职员。 院中可真熱鬧麻蹋,春花似錦、人聲如沸焊切。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽专肪。三九已至刹勃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嚎尤,已是汗流浹背荔仁。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乏梁。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓次洼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親遇骑。 傳聞我的和親對象是個殘疾皇子卖毁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容