【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_fileserror_page

6、相反操作

!~!~\* :分别为 区分大小写不匹配 及 不区分大小写不匹配 的正则

查找顺序和优先级

  1. 带有=的精确匹配优先
  2. 没有修饰符的精确匹配
  3. 正则表达式按照他们在配置文件中定义的顺序
  4. 带有^~修饰符的,开头匹配
  5. 带有~~\*修饰符的,如果正则表达式与 URI 匹配
  6. 没有修饰符的,如果指定字符串与 URI 开头匹配

另外详细说明:
匹配字符串分为两种:普通字符串(literal string)和正则表达式(regular expression),其中 ~~* 用于正则表达式, 其他前缀和无任何前缀都用于普通字符串。

匹配顺序是:

  1. 先匹配普通字符串,将最精确的匹配暂时存储;
  2. 然后按照配置文件中的声明顺序进行正则表达式匹配,只要匹配到一条正则表达式,则停止匹配,取正则表达式为匹配结果;
  3. 如果所有正则表达式都匹配不上,则取 1 中存储的结果;
  4. 如果普通字符串和正则表达式都匹配不上,则报 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;
}
关于我
loading