0. 前言
比如请求的url为:
http://www.liuvv.com/test/index.php?page=1
, 则uri 为
/test/index.php
1. location指令
1.1 location匹配uri的规则
1 |
location [ = | ~ | ~* | ^~ ] uri { ... } |
1.2 location匹配uri的优先级
- 使用正则定义的location在配置文件中出现的顺序很重要。因为找到第一个匹配的正则后,查找就停止了,后面定义的正则就是再匹配也没有机会了。
-
使用精确匹配可以提高查找的速度。例如经常请求
/
的话,可以使用=
来定义location。 -
优先级
=
>^~
> 正则
1.3 location 测试
1 |
location = / { |
1 |
levonfly@hk:~$ curl test.liuvv.com # 因为是= |
1.4 location @name的用法
@用来定义一个命名location。主要用于内部重定向,不能用来处理正常的请求。其用法如下:
1 |
location / { |
上例中,当尝试访问url找不到对应的文件就重定向到我们自定义的命名location(此处为custom)。
值得注意的是,命名location中不能再嵌套其它的命名location。
1.5 root和alias的区别
1 |
[root] |
1 |
location ^~ /t/ { |
如果一个请求的URI是/t/a.html时,web服务器将会返回服务器上的/www/root/html/t/a.html的文件。
1 |
[alias] |
1 |
location ^~ /t/ { # 特殊的规则是, alias必须以"/" 结束 |
1.6 nginx显示目录结构
nginx默认是不允许列出整个目录的。如需此功能, 在server或location 段里添加上autoindex on;
1 |
autoindex_exact_size off; |
1 |
location ^~ "/upload-preview" { |
1.7 URL尾部的
/
需不需要
-
如果URL结构是
https://domain.com/
的形式,尾部有没有/
都不会造成重定向。因为浏览器在发起请求的时候,默认加上了/
。虽然很多浏览器在地址栏里也不会显示/
。这一点,可以访问 baidu 验证一下。 -
如果URL的结构是
https://domain.com/some-dir/
。尾部如果缺少
/
将导致重定向。因为根据约定,URL尾部的/
表示目录,没有/
表示文件。所以访问
/some-dir/
时,服务器会自动去该目录下找对应的默认文件。如果访问
/some-dir
的话,服务器会先去找some-dir
文件,找不到的话会将some-dir
当成目录,重定向到/some-dir/
,去该目录下找默认文件。
2. rewirte规则
2.1 return指令
1 |
return code [text]; |
1 |
return 301 $scheme://www.baidu.com$request_uri; |
return 指令告诉 nginx 停止处理请求, 直接返回301代码和指定重写过的URL到客户端. $scheme是指协议(http),$request_uri指包含参数的完整URI
1 |
return (301 | 302 | 303 | 307) url; |
1 |
return (1xx | 2xx | 4xx | 5xx)["text"] |
1 |
return 401 "Access denied because token is expired or invalid"; |
2.2 rewrite指令
rewrite指令写在server和location里面, 规则会改变部分或整个用户的URL.
1 |
rewrite regex URL [flag] |
1 |
rewrite ^(/download/.*)/media/(\w+)\.?.*$ $1/mp3/$2.mp3 last; |
2.3 try_files指令
try_files指令写在server和location里面.
1 |
try_files file ... uri 或 try_files file ... = code |
1 |
location /images/ { |
-
1
try_files $uri $uri/ /index.php$is_args$args; #这样就能避免多余的?号
1 |
try_files /app/cache/ $uri @fallback; |
你也可以使用一个文件或者状态码(=404)作为最后一个参数,如果是最后一个参数是文件,那么这个文件必须存在。
1 |
location ~.*\.(gif|jpg|jpeg|png)$ { |
1 |
location ~.*\.(gif|jpg|jpeg|png)$ { |
这样才会先检查
/web/wwwroot/static/test.jpg
是否存在,不存在就取
/web/wwwroot/test.jpg
再不存在则返回404 not found
2.4 if指令
if不是系统级的指令, 是和rewrite配合的. if 必须写在server和location里面.
- 变量名: 如果是空字符串或”0”为FALSE
- = 判断相等, != 判断不相等
- ~ 和 ~*(不分区大小写) 将变量与正则匹配, 捕获可以用 $1 到 $9
- !~ 和 !~* 用作不匹配运算符
- 正则含有 } 或 ; 字符需要用引号括起来
-
常用判断指令
- -f 和 !-f 判断是否存在文件(file)
- -d 和 !-d 判断是否存在目录(directory)
- -e 和 !-e 判断是否存在文件或目录(exists)
- -x 和 !-x 判断文件是否可执行(execute)
1 |
if ($http_user_agent ~ Chrome) { |
3. proxy_pass模块
proxy_pass指令是将请求反向代理到URL参数指定的服务器上,URL可以是主机名或者IP地址+端口号的形式,例如:
1 |
proxy_pass http://proxy_server; |
3.1 基本配置
- proxy_set_header:设置服务器获取用户的主机名或者真实ip地址,以及代理者的真实ip地址。
- client_body_buffer_size:用于指定客户端请求主体缓冲区大小,可以理解为先保存到本地再传给用户
- proxy_connect_timeout:表示连接服务器的超时时间,即发起tcp握手等候响应的超时时间
- proxy_send_time:服务器的数据传回时间,在规定时间内服务器必须传回完所有数据,否则,nginx将断开这个连接
- proxy_read_time:设置nginx从代理的后端服务器获取数据的时间,表示连接建立成功后,+ nginx等待服务器的响应时间,其实是nginx已经进入服务器的排队中等候处理的时间。
- proxy_buffer_size:设置缓冲区大小,默认该缓冲区大小等于proxy_buffers设置的大小
- proxy_buffers:设置缓冲区的数量和大小,nginx从代理的服务器获取响应数据会放置到缓冲区
- proxy_busy_buffers_size:用于设置系统很忙时可以使用的proxy_buffers大小,官方推荐大小为proxy_buffers*2
- proxy_temp_file_write_size:指定proxy缓存临时文件的大小
3.2 proxy_set_header
1 |
语法: proxy_set_header field value; |
1 |
proxy_set_header Host $proxy_host; |
proxy_set_header也可以自定义参数,如:proxy_set_header test paroxy_test;
3.3 获取真实ip
1 |
proxy_set_header X-real-ip $remote_addr; |
3.4 常见配置解释
1 |
server { |
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
X-Forwarded-For 请求头格式非常简单,就这样:
1
X-Forwarded-For: client, proxy1, proxy2
可以看到,XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP。
1
X-Forwarded-For: IP0, IP1, IP2
-
proxy_set_header Host $http_host;
$host:请求中的主机头(HOST)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称(处理请求的server的server_name指令的值)。值为小写,不包含端口!!!!
如果客户端发过来的请求的header中有’HOST’这个字段时,
$http_host
和$host
都是原始的’HOST’字段比如请求的时候HOST的值是 www.csdn.net 那么反代后还是 www.csdn.net
如果客户端发过来的请求的header中没有有’HOST’这个字段时, 建议使用$host,这表示请求中的server name。
4. websocket反向代理
1 |
#必须添加的 |