nginx全局变量,rewrite实战,nginx的location配置

北城以北 提交于 2020-02-28 03:21:11

nginx全局变量

  • 如图,这是nginx 常用的全局变量
  • 第一个变量 $args 表示请求的参数
  • 比如 www.123.com/1.php 就是请求 1.php文件
  • 但是后面有一个问号 ?
  • 这个问号表示输入的参数的意思
  • 访问请求是可以输入参数的,如果有必要的话,也可以不输入参数
  • 总之参数会放在问号的后面,问号后面的 a=1&b=2 就是参数
  • nginx 接收到这个请求后,就会把参数的值放到 $args 全局变量里面去
  • 如图,在配置文件里面定义访问返回 $args 变量的值
  • 如图,这里模拟访问这个网站,并输入参数 a=1&b=2
  • 网站字符串之所以要用单引号括起来,是因为后面有特殊符号 & 存在
  • 不括起来会导致系统判断错误
  • 可以看到访问之后,系统返回的值是 a=1&b=2
  • 所以问号后面不管写了什么,这些字符串都会作为一个整体赋值到 $args 变量里面去
  • 如图,使用 -I 查看头文件信息
  • 可以看到,头文件信息里面有 Content-Length 和 Content-Type
  • 这两个值也是记录在 $content_length 和 $conten_type 全局变量里面
  • 调用这两个全局变量就可以获得访问请求的这两个值
  • 如图,配置文件里面的 root 后面的值,也就是网站的根目录路径
  • 就是全局变量 $document_root 的值
  • 也就是说这个全局变量里面保存了虚拟主机配置文件里面定义的根目录路径
  • 全局变量 $document_uri 就是不包含参数的访问请求的路径
  • 比如访问某个网站的 1.php 文件
  • 那么这个请求的 $document_uri 就是 1.php
  • 不包含前面的域名,如果后面有问号
  • 问号后面是参数,那么也不包含问号和后面的参数
  • 也就是去掉域名,去掉后面的参数,就是document_uri
  • 全局变量 $host 的值就是虚拟主机的域名
  • 全局变量 $http_user_agent 保存的是浏览器标识
  • 可以使用 curl -A 参数自定义一个浏览器标识
  • 这个浏览器标识访问的时候就会保存到 $http_user_agent 变量里面
  • 如图,在配置文件里面设置返回 $http_user_agent 变量
  • 然后 curl -A 自定义一个浏览器标识
  • 可以看到,返回的变量值就是自定义的浏览器标识
  • 全局变量 $http_cookie 就是客户端的cookie信息
  • 全局变量 $limit_rate 就是网络速率的值
  • 如果nginx配置了显示网络速率,这个变量就是网络速率的值
  • 如果没有配置显示网络速率,这个变量的值就是 0
  • 如图,这也是常用的全局变量
  • 全局变量 $remote_addr
  • 记录的就是客户端的公网 ip
  • 比如我从本机访问一个服务器
  • 这个全局变量就会记录我使用的机器的公网 ip
  • 也就是访问请求是从哪个 ip 过来的
  • 全局变量 $remote_port
  • 就是访问的客户端的端口号
  • 也就是请求是从客户端的哪个端口出来的
  • 全局变量 $remote_user
  • 记录的是客户端访问使用的用户名
  • 如果服务器设置了访问认证的话
  • 客户端访问的时候,是需要输入用户名密码认证通过后,才能正常访问的
  • 认证的用户名就会被记录到这个变量里面
  • 全局变量 $request_body_file
  • 如果服务器做反向代理,发给后端服务器的本地资源名称会记录在这个变量里面
  • 全局变量 $request_method
  • 这个变量记录了访问请求使用的方式的名称
  • 不同的方式有 get/put/delete 等
  • 如图,访问网站可以返回 $request_method 变量的值
  • 配置文件设置访问日志,access_log /tmp/2.log
  • 如果不设置返回 $request_method 的值
  • 想要查看使用的 request_method 就可以在访问日志里面看到
  • 如图,curl 的时候,使用 -I 参数
  • 那么访问请求的方式就是 head 方法
  • 如果不使用 -I 参数,查看日志可以看到
  • 访问请求的方式就是 get 方法
  • 全局变量 $request_filename
  • 这个变量就等于 $document_root/$document_uri 这两个变量连起来的组合
  • 全局变量 $request_uri
  • 这个变量等于 document_uri + $args
  • 也就是uri+参数
  • 全局变量 $scheme
  • 这个变量记录的是请求使用的协议,例如 ftp,http,https之类的
  • 局变量 $server_protocol
  • 这个变量记录的是使用的协议的版本,例如 http/1.0 或者 http/2.0 之类的
  • 如图,这些也是常用的全局变量
  • 这里面,全局变量 $uri 的值跟 $document_uri 的值是一样的
  • 全局变量 $http_referer
  • 这个变量记录的就是请求的来源
  • 用浏览器访问 a.com 网页
  • 在 a.com 网页里面,访问 b.com 网站
  • 那么在 b.com 网站的服务器里面的 http_referer变量
  • 就会记录这个访问请求的来源是 a.com
  • 这个 http_referer 的值是浏览器生成的,某些浏览器可能不会生成这个值
  • 那么 http_referer 的值就是 null
  • 如图,使用 curl 模拟,参数 -e 可以指定一个 http_referer
  • 可以看到,返回的 http_referer 全局变量的值跟 参数-e 设置的值是一样的

rewrite实战

  • 如图,这是一个 rewrite 跳转的例子
  • 这里 /(.*) 表示不管访问当前虚拟主机根目录下的任何文件
  • 都跳转到 www.1.com 网站下面的同名文件上去
  • 这里 $1 表示第一个括号内容,第一个括号是 (.*)
  • 如图,这个例子,server name 有两个,分别是 www.2.com 和 2.com
  • 下面是 if 语句判断,$host 是内置变量,表示访问请求访问的主机名称
  • 也就是 server name
  • 这里判断访问请求不等于 www.2.com 的时候
  • 符号 != 表示不等于
  • 才执行if语句里面的 rewrite 语句
  • 效果就是跳转到 www.2.com 网站下面的同名文件
  • 因为这个虚拟主机有两个 server name
  • 如果用户访问 2.com 这个域名下的文件时
  • 就会跳转到 www.2.com 这个域名下的同名文件
  • 如图,这个例子是使用 rewrite 使http 跳转到 https
  • 本来是访问 http 80 端口的
  • 这里使用了 rewrite 跳转到 https 443 端口
  • 如图,rewrite 语句 当访问当前网站下任意文件时
  • 都会跳转到 https://www.2.com/$1
  • 当前网站的域名就是 www.2.com
  • 但是当前网站是 http 80 端口
  • 而不是 https 443 端口
  • 所以访问 http://www.2.com 就会跳转到 https://www.2.com
  • 下面的同名文件去
  • 如图,这里把网站根目录注释掉了
  • 这个例子是把访问请求跳转到另外一个网站下面的bbs目录下的同名文件上去
  • 如果访问 bbs.2.com 网站下的某个文件
  • 就会 rewrite 到 www.2.com/bbs/ 这个网站bbs目录下的同名文件
  • 这个就是二级目录跳转
  • 如图,这个例子是静态请求分离的用法
  • 意思就是让静态文件的请求进行跳转
  • 比如一台服务器是国外的,静态文件因为比较大,访问会比较慢
  • 这时候可以把静态文件的请求跳转到国内的服务器上去
  • 这样静态文件请求的速度就会比较快了
  • 这里使用了 if 语句进行判断,也可以使用 location 来匹配
  • 这里是内置变量 $uri 匹配 jpg 或者 gif 等等后缀结尾的文件
  • 符号 $ 的意思就是 以...结尾的意思
  • 所以前面括号内的 jpg 就表示以 jpg 结尾,或者以 png 结尾之类的意思
  • 也就是说,以括号内的字符串为后缀结尾的文件请求
  • 就会执行 rewrite 语句
  • 跳转访问到 img.2.com/ 网站下的同名文件去
  • 如图,这是一个防盗链的例子
  • 防止别人引用自己服务器上面的资源
  • 首先 location 匹配 jep,png 等等后缀的文件名称
  • 如果有用户访问这么后缀的文件,就会执行 location 里面的规则
  • 第一条是放行的规则,就是符合条件的访问就放行,不做限制
  • vaild_referers 表示白名单的 referers
  • none 表示 referers 为空的访问请求
  • blocked 表示 referers 开头不是 http 或者 https 的白名单 referers
  • server_names 表示域名,这个字符串后面就是定义 白名单的域名
  • 写在 server_names 后面的域名都属于白名单,可以使用正则表达式
  • 如果访问请求的referers 符合以上规则,就可以顺利访问
  • 下面的 if 语句是不符合以上referers 的访问请求就会执行
  • 里面的 $invalid_referer 表示黑名单,凡是不在白名单里面的域名都属于黑名单
  • if($invalid_referer) 是判断访问请求的referers 是否属于黑名单
  • 如果是,就执行 if 里面的语句,这里是返回 403
  • 如图,这是伪静态的例子
  • 伪静态意思是,用户访问一个静态页面的时候
  • 跳转到动态页面去,这样访问比较快
  • 如图,这是写在nginx配置文件里面的设置
  • 有时候需要用到比较复杂的 if 判断,但是 nginx 不支持 if语句 嵌套
  • 可以使用这种方法进行多重 if 判断
  • 首先 set $a 0;
  • 这是自定义变量的语句,$a 就是自定义变量 a
  • 前面 set 表示定义变量,后面的 0 表示把 0 赋值给 $a 变量
  • 然后 if 判断,如果 request_uri 变量的值 不匹配 以 /abc/ 开头
  • 就执行里面的语句,符号 ^ 表示以....开头的意思
  • 里面的语句 set $a "${a}1";
  • 这也是重新给变量 a 赋值的意思
  • 这里 "${a}1" 的意思是把原来变量 a 的值跟 1 进行字符串叠加
  • 原来 a 的值是 0 , 重新赋值后就变成了 01
  • 在shell里面,要进行字符串叠加,写 $a1 就行了
  • 但是在 nginx 里面这样写会出现问题
  • 所以写成 ${a}1 这样就不会出现问题
  • 下面第二个 if 判断
  • 变量 http_user_agent 匹配 IE 或者 chrome
  • 如图匹配成功,就执行里面的语句
  • 里面也是一个赋值的语句,set $a "${a}2";
  • 这也是把变量 a 原来的值 跟 2 进行字符串叠加
  • 如果已经执行了上面第一个if判断
  • 那么 a 的值就是 01 ,再执行这条语句后,a的值就变成了 012
  • 最后一个 if 判断是,如果 a 的值 = “012”
  • 就返回 406
  • 这就是多重 if 判断的一个例子

nginx 的 location 配置

  • 如图,首先安装一下这个模块
  • 这个模块可以支持在nginx 里面使用 echo 命令
  • 使用 git 把模块的源码 clone 到本机
  • 如果系统没有 git 命令,使用 yum install -y git 安装一下
  • 然后进入 /usr/local/src 目录,再使用 git 命令
  • 因为会下载到当前目录下,所以先进入专门放下载文件的目录
  • cd 进入 nginx 安装包的目录 nginx-1.14.0/
  • 然后使用 make clean 把之前的的安装配置清空
  • /usr/local/nginx/sbin/nginx -V 可以查看版本信息和之前使用的安装配置
  • 然后重新编译一遍 ./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/echo-nginx-module
  • 就是比之前增加了 --add-module 引用刚才下载好的模块目录的路径
  • 重新编译
  • 配置通过之后再使用 make 编译
  • 如图,重新编译之后重启一下就行了
  • 然后随便找一个虚拟主机配置文件
  • 如图,使用 location /abc/ { echo 123; }
  • 使用 echo 要写在 location 里面,不然会报错
  • 如果写法正确,使用 nginx -t 检测的时候还是报错,说明echo 模块没有安装成功
  • 如图,curl 访问 www.2.com/abc/ 下面随便一个文件
  • 可以看到,返回了 123
  • 安装这个模块,主要是方便测试,可以很容易看到 location 返回什么
  • 在生产环境中是不使用的
  • 如图,这是 location 的语法规则
  • location 后面跟的符号主要有图中的 5 种
  • 如图,这是五种符号的优先级顺序
  • 如果五种符号的 location 同时存在,会按照这个优先级来进行匹配
  • 如图,先测试 / 和 ~* 两个匹配符合的优先级
  • 符号 / 是匹配根目录后面的 abc 的,abc必须紧跟着根目录的 /
  • 符号 ~* 是模糊匹配,只要后面uri里面存在 abc 字段,就可以匹配成功,位置无所谓
  • 如图,测试,同时匹配这两个 location 的时候
  • 返回的是 ~* ,说明同时匹配发生时
  • 符号 ~* 优先级比 / 要高
  • 如图,测试符号 ~ 和 ~* 的优先级
  • 这是测试结果,第一次测试,返回的是符号 /
  • 因为符号 ~ 在上面
  • 然后把符号 ~ 和 ~* 的location 位置互相调换一下
  • 让符号 ~* 的 location 在上面
  • 再测试一遍,返回的就是 ~*
  • 这说明,符号 ~ 和 ~* 的优先级是一样的
  • 先匹配哪个看位置,因为程序是从上到下来执行的
  • 这两个符号优先级一样,所以谁在上面,就先匹配谁
  • 匹配之后,就不继续往下匹配了
  • 如图,再测试符号 ~* 和 ^~ 的优先级
  • 因为 ~* 是模糊匹配,所以匹配 abc 就行了
  • 但是 ^~ 的意思是匹配 以....开头 的意思
  • 所以要写成 /abc ,/ 是根目录,后面跟 abc
  • 就表示这个 uri 是以 abc 开头的
  • 如图,可以看到,返回的是 ^~
  • 所以 ^~ 的优先级更高
  • 如图,测试符号 ^~ 和 = 的优先级
  • 因为 = 是精确匹配,所以路径要写精确
  • 符号 ^~ 是模糊匹配,只要写 abc 开头就行了,后面跟什么文件都可以
  • 如图,可以看到,返回的是 =
  • 说明这两个匹配同时发生的时候,= 的优先级更高
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!