nginx 常用全局变量

变量 说明

:-------- :-----

$args //请求中的参数,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2

$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,不包含后面的参数

$host //主机头,也就是域名,请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称

$http_user_agent //客户端的详细信息,也就是浏览器的标识,用curl -A可以指定

$http_cookie //客户端的cookie信息

$limit_rate //如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0

$remote_addr //客户端的公网ip

$remote_port //客户端的端口

$remote_user //如果nginx有配置认证,该变量代表客户端认证的用户名

$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 //服务器的端口号

$uri //和$document_uri相同

$http_referer //客户端请求时的referer,通俗讲就是该请求是通过哪个链接跳过来的,用curl -e可以指定

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

[root@jinkai01 vhost]# curl -x127.0.0.1:80 'www.a.com/1.php?a=1&b=2' -I

HTTP/1.1 301 Moved Permanently

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 13:25:18 GMT

Content-Type: text/html

Content-Length: 169

Connection: keep-alive

Location: http://www.b.com/1.php?a=1&b=2

示例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

[root@jinkai01 vhost]# curl -x127.0.0.1:80 'www.a.com/1.php?a=1&b=2' -I

HTTP/1.1 404 Not Found

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 13:27:33 GMT

Content-Type: text/html

Content-Length: 153

Connection: keep-alive

[root@jinkai01 vhost]# curl -x127.0.0.1:80 'a.com/1.php?a=1&b=2' -I

HTTP/1.1 301 Moved Permanently

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 13:27:44 GMT

Content-Type: text/html

Content-Length: 169

Connection: keep-alive

Location: http://www.a.com/1.php?a=1&b=2

示例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;

}

[root@jinkai01 vhost]# curl -x127.0.0.1:80 'www.a.com/1.php?a=1&b=2' -I

HTTP/1.1 301 Moved Permanently

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 13:29:41 GMT

Content-Type: text/html

Content-Length: 169

Connection: keep-alive

Location: https://www.a.com/1.php?a=1&b=2

示例4(域名访问二级目录)

server{

listen 80;

server_name blog.a.com;

index index.html;

rewrite /(.*) http://www.a.com/blog/$1 permanent;

}

[root@jinkai01 vhost]# curl -x127.0.0.1:80 'blog.a.com/1.php?a=1&b=2' -I

HTTP/1.1 301 Moved Permanently

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 13:31:00 GMT

Content-Type: text/html

Content-Length: 169

Connection: keep-alive

Location: http://www.a.com/blog/1.php?a=1&b=2

示例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;

}

}

[root@jinkai01 vhost]# curl -x127.0.0.1:80 'www.a.com/1.png' -I

HTTP/1.1 301 Moved Permanently

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 13:33:15 GMT

Content-Type: text/html

Content-Length: 169

Connection: keep-alive

Location: http://img.a.com/1.png

示例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定义白名单,invalid_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;

​ }

}

[root@jinkai01 vhost]# curl -A "firefox1.1" -e "http://jinkai.com/1.html" -x127.0.0.1:80 'www.a.com/1.png' -I

HTTP/1.1 403 Forbidden

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 14:01:02 GMT

Content-Type: text/html

Content-Length: 153

Connection: keep-alive

[root@jinkai01 vhost]# curl -A "firefox1.1" -e "http://a.com/1.html" -x127.0.0.1:80 'www.a.com/1.png' -I

HTTP/1.1 404 Not Found

Server: nginx/1.18.0

Date: Tue, 22 Sep 2020 14:01:17 GMT

Content-Type: text/html

Content-Length: 153

Connection: keep-alive

示例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;

}

示例8:rewrite多个条件的并且

location /{

​ set $rule 0;

​ if ($document_uri !~ '^/abc')

​ {

​ set $rule "${rule}1";

​ }

​ if ($http_user_agent ~* 'ie6|firefox')

​ {

​ set $rule "${rule}2";

​ }

​ if ($rule = "012")

​ {

​ rewrite /(.*) /abc/$1 redirect;

​ }

}

Nginx的location配置

安装第三方模块echo-nginx-module

安装git:

yum install -y git

克隆源码:

git clone https://github.com/openresty/echo-nginx-module.git

进入nginx源码包目录,清空原先的编译

cd /usr/local/src/nginx-1.18.0

make clean

在原先编译的基础上进行再次编译

nginx -V 查看原先的编译模块

configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module

重新编译

./configure --prefix=/usr/local/nginx --with-http_ssl_module

--add-module=/usr/local/src/echo-nginx-module

make && make install

Location的语法

nginx location语法规则:location [=|~|~*|^~] /uri/ { … }

nginx的location匹配的变量是$uri(请求uri不包含查询字符串,如http://localhost:8080/test?id=10,请求uri是/test)

location = /uri =开头表示精确前缀匹配,只有完全匹配才能生效。

location ^~ /uri ^~开头表示普通字符串匹配上以后不再进行正则匹配。

location ~ pattern ~开头表示区分大小写的正则匹配。

location ~* pattern ~*开头表示不区分大小写的正则匹配。

location /uri 不带任何修饰符,表示前缀匹配。

location / 通用匹配,任何未匹配到其他location的请求都会匹配到。

符号 说明

= 表示精确匹配|

^~ 表示uri以指定字符或字符串开头

~ 表示区分大小写的正则匹配

~* 表示不区分大小写的正则匹配

/ 通用匹配,如果没有其他匹配,任何请求都会匹配到

规则优先级

= 高于 ^~ 高于 ~* 等于 ~ 高于 /

注意:正则匹配会根据匹配顺序,找到第一个匹配的正则表达式后将停止搜索。普通字符串匹配则无视顺序,只会选择最精确的匹配。

规则示例

location = "/12.jpg" { ... }

如:精确匹配开头是12.jpg

www.aminglinux.com/12.jpg 匹配

www.aminglinux.com/abc/12.jpg 不匹配

location ^~ "/abc/" { ... }

如:匹配以/abc/开头的

www.aminglinux.com/abc/123.html 匹配

www.aminglinux.com/a/abc/123.jpg 不匹配

location ~ "png" { ... }

如:匹配区分大小包含png

www.aminglinux.com/aaa/bbb/ccc/123.png 匹配

www.aminglinux.com/aaa/png/123.html 匹配

location ~* "png" { ... }

如:匹配不区分大小写包含png

www.aminglinux.com/aaa/bbb/ccc/123.PNG 匹配

www.aminglinux.com/aaa/png/123.html 匹配

location /admin/ { ... }

如:匹配以admin开头的

www.aminglinux.com/admin/aaa/1.php 匹配

www.aminglinux.com/123/admin/1.php 不匹配

小常识

有些资料上介绍location支持不匹配 !~,

如: location !~ 'png'{ ... }

这是错误的,location不支持 !~

如果有这样的需求,可以通过if来实现,

如: if ($uri !~ 'png') { ... }

注意:location优先级小于if

nginx location优先级

= 高于 ^~ 高于 ~* 等于 ~ 高于 /

对比/和~

示例1:

server{

​ listen 80;

​ server_name www.aminglinux.com;

​ root /tmp/123.com;

​ location /abc/

​ {

​ echo "/";

​ }

​ location ~ 'abc'

​ {

​ echo "~";

​ }

}

测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/1.png'

结果是:~

对比~和~*

示例2:

server

{

​ listen 80;

​ server_name www.aminglinux.com;

​ root /tmp/123.com;

​ location ~ 'abc'

​ {

​ echo '~';

​ }

​ location ~* 'abc'

​ {

​ echo '~*';

​ }

}

测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/123.html'

结果是:~

示例3:

server

{

​ listen 80;

​ server_name www.aminglinux.com;

​ root /tmp/123.com;

​ location ~* 'abc'

​ {

​ echo '~*';

​ }

​ location ~ 'abc'

​ {

​ echo '~';

​ }

}

测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/123.html'

结果是:~*

结论:~和~*优先级其实是一样的,如果两个同时出现,配置文件中哪个location靠前,哪个生效。

对比^~和~

示例4:

server

{

​ listen 80;

​ server_name www.aminglinux.com;

​ root /tmp/123.com;

​ location ~ '/abc'

​ {

​ echo '~';

​ }

​ location ^~ '/abc'

​ {

​ echo '^~';

​ }

}

测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/123.html

结果是:^~

对比=和^~

示例5:

server

{

​ listen 80;

​ server_name www.aminglinux.com;

​ root /tmp/123.com;

​ location ^~ '/abc.html'

​ {

​ echo '^~';

​ }

​ location = '/abc.html'

​ {

​ echo '=';

​ }

}

​ 测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc.html

结果是:=