【Nginx】location指令详解
nginx 配置方式
Nginx 的 HTTP 配置主要包括三个区块,结构如下:
http { //这个是协议级别
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
gzip on;
server { //这个是服务器级别
listen 80;
server_name localhost;
location / { //这个是请求级别
root html;
index index.html index.htm;
}
}
}
location 区段
通过指定模式来与客户端请求的 URI 相匹配,基本语法如下:location [=|~|~*|^~|@] pattern{……}
简要说明:中括号可以不写任何参数,此时称为一般匹配,也可以写参数。因此,大类型可以分为 3 种:
location = patt {} [精准匹配]
location patt{} [一般匹配]
location ~ patt{} [正则匹配]
1.一般匹配/没有修饰符
可以理解为左前缀匹配(like pattern%),这种情况下,匹配那些以指定的 patern 开头的 URI,注意这里的 URI 只能是普通字符串,不能使用正则表达式,如:
server {
server_name xx.com;
location /abc {
}
}
那么,下面的链接都是匹配的,只要以次字符串开始就能匹配。
http://xx.com/abc
http://xx.com/abc?p1
http://xx.com/abc/
http://xx.com/abcde
2、精准匹配
= 表示:必须与指定的模式精确匹配
完全匹配指定的 pattern ,且这里的 pattern 被限制成简单的字符串,也就是说这里不能使用正则表达式.
server {
server_name sish
location = /abc {
}
}
那么,如下是对的:
http://xx.com/abc
http://xx.com/abc?p1
如下是错的:
http://xx.com/abc/
http://xx.com/abcde
3、正则匹配
对大小写敏感(在 window 上无效),且 pattern 须是正则表达式
~
表示:指定的正则表达式要区分大小写
server {
server_name baidu.com;
location ~ ^/abc$ { #~和^有个空格
}
}
其中$
表示匹配到结束
那么,如下是对的:
http://xx.com/abc
http://xx.com/abc?p1=11&p2=22
如下是错的:
http://xx.com/ABC
http://xx.com/abc/
http://xx.com/abcde
~*
表示:指定的正则表达式不区分大小写,不区分大小写,pattern 须是正则表达式
server {
server_name baidu.com;
location ~* ^/abc$ {
}
}
那么,如下是对的:
http://xx.com/abc
http://xx.com/ABC
http://xx.com/abc?p1=11&p2=22
如下是错的:
http://xx.com/abc/
http://xx.com/abcde
4、无修饰符行为
^~
类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他模式了。
5、内部访问行为
@
:定义命名 location 区段,这些区段客户段不能访问,只可以由内部产生的请求来访问,如try_files
或error_page
等
6、相反操作
!~
和!~\*
:分别为 区分大小写不匹配 及 不区分大小写不匹配 的正则
查找顺序和优先级
- 带有
=
的精确匹配优先 - 没有修饰符的精确匹配
- 正则表达式按照他们在配置文件中定义的顺序
- 带有
^~
修饰符的,开头匹配 - 带有
~
或~\*
修饰符的,如果正则表达式与 URI 匹配 - 没有修饰符的,如果指定字符串与 URI 开头匹配
另外详细说明:
匹配字符串分为两种:普通字符串(literal string)和正则表达式(regular expression),其中 ~
和~*
用于正则表达式, 其他前缀和无任何前缀都用于普通字符串。
匹配顺序是:
- 先匹配普通字符串,将最精确的匹配暂时存储;
- 然后按照配置文件中的声明顺序进行正则表达式匹配,只要匹配到一条正则表达式,则停止匹配,取正则表达式为匹配结果;
- 如果所有正则表达式都匹配不上,则取 1 中存储的结果;
- 如果普通字符串和正则表达式都匹配不上,则报 404 NOT FOUND。
location=/uri
: =
开头表示精确前缀匹配,只有完全匹配才能生效。
location ^~ /uri
: ^~
开头表示普通字符串匹配上以后不再进行正则匹配。
location ~ pattern
: ~
开头表示区分大小写的正则匹配。
location ~* pattern
: ~\*
开头表示不区分大小写的正则匹配。
location /uri
: 不带任何修饰符,表示前缀匹配。
location /
: 通用匹配,任何未匹配到其他 location 的请求都会匹配到。
注意:正则匹配会根据匹配顺序,找到第一个匹配的正则表达式后将停止搜索。普通字符串匹配则无视顺序,只会选择最精确的匹配。
root 、alias、proxy_pass 指令区别
别名使用方法
alias——别名配置,用于访问文件系统,在匹配到 location 配置的 URL 路径后,指向 alias 配置的路径,
location /img/ {
alias /var/www/image/;
}
若按照上述配置的话,则访问/img/
目录里面的文件时,ningx 会自动去/var/www/image/
目录找文件
请求/img/1.jpg(
省略了协议和域名),将会返回文件/var/www/image/1.jpg
。
如果 alias
配置在正则匹配的 location 内,则正则表达式中必须包含捕获语句(也就是括号()),而且 alias 配置中也要引用这些捕获值。如:
location ~* /img/(.+\.(gif|png|jpeg)) {
alias /usr/local/images/$1;
}
请求中只要能匹配到正则,比如/img/flower.png
或者 /resource/img/flower.png
,都会转换为请求/usr/local/images/flower.png
。
root 使用方法
root——根路径配置,用于访问文件系统,在匹配到 location 配置的 URL 路径后,指向 root 配置的路径,并把请求路径附加到其后
location /img/ {
root /var/www/image;
}
若按照这种配置的话,则访问/img/目录下的文件时,nginx 会去/var/www/image/img/目录下找文件。
alias 是一个目录别名的定义,root 则是最上层目录的定义。
还有一个重要的区别是 alias 后面必须要用“/”结束,否则会找不到文件的。。。而 root 则可有可无~~
proxy_pass 使用方法
proxy_pass
——反向代理配置,用于代理请求,适用于前后端负载分离或多台机器、服务器负载分离的场景,在匹配到 location 配置的 URL 路径后,转发请求到 proxy_pass 配置额 URL,是否会附加 location 配置路径与 proxy_pass 配置的路径后是否有"/"有关,有"/"则不附加,如:
location /test/ {
proxy_pass http://127.0.0.1:8080/;
}
请求/test/1.jpg,将会被 nginx 转发请求到 http://127.0.0.1:8080/1.jpg
(未附加/test/路径)
推荐必须的 location
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说.
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://127.0.0.1:88;
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /\.
{
deny all; # 其他的任意后缀都不让其访问;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
location /
{
try_files $uri @apache; #try_files 将尝试你列出的文件并设置内部文件指向
}
location @apache
{
internal; # internal指令指定某个location只能被“内部的”请求调用,外部的调用请求会返回”Not found”
proxy_pass http://127.0.0.1:88;
proxy_connect_timeout 300s;
proxy_send_timeout 900;
proxy_read_timeout 900;
proxy_buffer_size 32k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_redirect off;
proxy_hide_header Vary;
proxy_set_header Accept-Encoding '';
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}