--Nginx全局變量、rewrite實戰、nginx的location配置
一、nginx全局變量
nginx 主配置文件中的log_format,常用全局變量:
https://github.com/aminglinux/nginx/blob/master/rewrite/variable.md

變量
說明
$args
請求中的參數,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2
$body_bytes_sent
服務器發送給客戶端的響應body字節數
$content_length
HTTP請求信息里的"Content-Length"
$conten_type
HTTP請求信息里的"Content-Type"
$document_root
nginx虛擬主機配置文件中的root參數對應的值
$document_uri
當前請求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的$document_uri就是1.php,不包含后面的參數
$http_referer
記錄此次請求是從哪個連接訪問過來的,可以根據該參數進行防盜鏈設置
$host
主機頭,也就是域名
$http_user_agent
客戶端的詳細信息,也就是瀏覽器的標識,用curl -A可以指定
$http_cookie
客戶端的cookie信息
$http_x_forwarded_for
當前端有代理服務器時,設置web節點記錄客戶端地址的配置,此參數生效的前提是代理服務器也要進行相關的x_forwarded_for設置
$limit_rate
如果nginx服務器使用limit_rate配置了顯示網絡速率,則會顯示,如果沒有設置, 則顯示0
$remote_addr
客戶端的公網ip
$remote_port
客戶端的port
$remote_user
如果nginx有配置認證,該變量代表客戶端認證的用戶名
$request
請求的URI和HTTP協議,如“GET /article-10000.html HTTP/1.1”
$request_body_file
做反向代理時發給后端服務器的本地資源的名稱
$request_method
請求資源的方式,GET/PUT/DELETE等
$request_filename
當前請求的資源文件的路徑名稱,相當于是$document_root/$document_uri的組合
$request_uri
請求的鏈接,包括$document_uri和$args
$scheme
請求的協議,如ftp,http,https
$server_protocol
客戶端請求資源使用的協議的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr
服務器IP地址
$server_name
服務器的主機名
$server_port
服務器的端口號
$status
http狀態碼,記錄請求返回的狀態碼,例如:200、301、404等
$uri
和$document_uri相同
$http_referer
客戶端請求時的referer,通俗講就是該請求是通過哪個鏈接跳過來的,用curl -e可以指定
$time_local
記錄訪問時間與時區,如18/Jul/2014:17:00:01 +0800
二、rewrite實戰
域名跳轉(域名重定向)
示例1(不帶條件的):
server{
listen 80;
server_name www.a.com;
root /data/wwwroot/www.a.com;
index index.html;
rewrite /(.*) http://www.b.com/$1 permanent;
}
訪問a.com跳轉到b.com

示例2(帶條件的):
server{
listen 80;
server_name www.a.com a.com;
root /data/wwwroot/www.a.com;
index index.html;
if ($host != 'www.a.com')
{
rewrite /(.*) http://www.a.com/$1 permanent;
}
}
通過判斷條件,如果$host不等于www.a.com的,跳轉到www.a.com

示例3(http跳轉到https):
server{
listen 80;
server_name www.a.com;
root /data/wwwroot/www.a.com;
index index.html;
rewrite /(.*) https://www.a.com/$1 permanent;
}

示例4(域名訪問二級目錄)
server{
listen 80;
server_name blog.a.com;
index index.html;
rewrite /(.*) http://www.a.com/blog/$1 permanent;
}

示例5(靜態請求分離)
server{
listen 80;
server_name www.a.com;
location ~* ^.+.(jpg|jpeg|gif|css|png|js)$
{
rewrite /(.*) http://img.a.com/$1 permanent;
}
}
或者:
server{
listen 80;
server_name www.a.com;
index index.html;
if ( $uri ~* 'jpg|jpeg|gif|css|png|js$')
{
rewrite /(.*) http://img.a.com/$1 permanent;
}
}

防盜鏈
示例6
server{
listen 80;
server_name www.a.com;
location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$
{
valid_referers none blocked server_names *.a.com a.com *.tobe.com tobe.com;
if ($invalid_referer)
{
rewrite /(.*) http://img.a.com/images/forbidden.png;
}
}
.......
}
說明:這里是通配,跟正則里面的不是一個意思,valid_referers定義白名單,none指的是referer不存在、為空的情況(curl -e 測試),
blocked指的是referer頭部的值被防火墻或者代理服務器刪除或者偽裝的情況,
該情況下,referer頭部的值不以http://或者https://開頭(curl -e 后面跟的referer不以http://或者https://開頭)。
或者:
location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$
{
valid_referers none blocked server_names *.a.com *.tobe.com a.com tobe.com;
if ($invalid_referer)
{
return 403;
}
}
偽靜態
示例7(discuz偽靜態):
location / {
rewrite ^([^.]*)/topic-(.+).html$ $1/portal.php?mod=topic&topic=$2 last;
rewrite ^([^.]*)/forum-(w+)-([0-9]+).html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;
rewrite ^([^.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+).html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;
rewrite ^([^.]*)/group-([0-9]+)-([0-9]+).html$ $1/forum.php?mod=group&fid=$2&page=$3 last;
rewrite ^([^.]*)/space-(username|uid)-(.+).html$ $1/home.php?mod=space&$2=$3 last;
rewrite ^([^.]*)/(fid|tid)-([0-9]+).html$ $1/index.php?action=$2&value=$3 last;
}
rewrite多個條件的并且
示例8:
location /{
set $rule 0; #值為0
if ($document_uri !~ '^/abc') #!~不匹配以abc開頭的
{
set $rule "${rule}1"; #01
}
if ($http_user_agent ~* 'ie6|firefox')
{
set $rule "${rule}2"; #012
}
if ($rule = "012")
{
rewrite /(.*) /abc/$1 redirect;
}
}
當滿足兩個條件不以abc開頭,并且http_user_agent為ie6或firefox時,跳轉到http://www.a.com/aaa/,不滿足其中的一個條件時,返回了404

三、nginx的location配置
安裝第三方模塊echo-nginx-module
cd /usr/local/src/
git clone https://github.com/openresty/echo-nginx-module.git
nginx編譯安裝后的操作:
cd /usr/local/src/nginx-1.16.1
重新編譯
./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/echo-nginx-module
make && make install
/usr/local/nginx/sbin/nginx -V
測試中使用,可以在虛擬主機配置文件中直接使用,如:echo 123;

location語法:
nginx location語法規則:location [=|~|~*|^~] /uri/ { … }
nginx的location匹配的變量是$uri
符號說明=表示精確匹配^~表示uri以指定字符或字符串開頭~表示區分大小寫的正則匹配~*表示不區分大小寫的正則匹配/通用匹配,任何請求都會匹配到
規則優先級:
= 高于 ^~ 高于 ~* 等于 ~ 高于 /
規則示例:
location = "/12.jpg" { ... }
如:
www.a.com/12.jpg 匹配
www.a.com/abc/12.jpg 不匹配
location ^~ "/abc/" { ... }
如:
www.a.com/abc/123.html 匹配
www.a.com/a/abc/123.jpg 不匹配
location ~ "png" { ... }
如:
www.a.com/aaa/bbb/ccc/123.png 匹配
www.a.com/aaa/png/123.html 匹配
location ~* "png" { ... }
如:
www.a.com/aaa/bbb/ccc/123.PNG 匹配
www.a.com/aaa/png/123.html 匹配
location /admin/ { ... }
如:
www.a.com/admin/aaa/1.php 匹配
www.a.com/123/admin/1.php 不匹配
小常識:
有些資料上介紹location支持不匹配 !~,
如: location !~ 'png'{ ... }
這是錯誤的,location不支持 !~
如果有這樣的需求,可以通過if來實現,
如: if ($uri !~ 'png') { ... }
注意:location優先級小于if