Location指令是nginx中最关键的指令之一,location指令的功能是用来匹配不一样的url请求,进而对请求作不一样的处理和响应,这其中较难理解的是多个location的匹配顺序,本文会做为重点来解释和说明。javascript
开始以前先明确一些约定,咱们输入的网址叫作请求URI,nginx用请求URI与location中配置的URI作匹配。php
首先咱们先简单了解Nginx的文件结构,Nginx的HTTP配置主要包括三个区块,结构以下:css
Global: nginx 运行相关 Events: 与用户的网络链接相关 http http Global: 代理,缓存,日志,以及第三方模块的配置 server server Global: 虚拟主机相关 location: 地址定向,数据缓存,应答控制,以及第三方模块的配置
从上面展现的nginx结构中能够看出location属于请求级别配置,这也是咱们最经常使用的配置。html
⚠️ 全部的全部的全部的指令,都要以 ; 结尾
Location 块经过指定模式来与客户端请求的URI相匹配。
Location基本语法:前端
location [ = | ~ | ~* | ^~ ] /uri/ { … } location @/name/ { … }
参数 | 解释 |
---|---|
空 | location后没有参数直接跟着URI,表示前缀匹配,表明跟请求中的URI从头开始匹配。 |
= | 用于标准 uri 前,要求请求字符串与其严格匹配,成功则当即处理,nginx中止搜索其余匹配。 |
^~ | 用于标准 uri 前,并要求一旦匹配到就会当即处理,再也不去匹配其余的那些个正则 uri,通常用来匹配目录 |
~ | 用于正则 uri 前,表示 uri 包含正则表达式, 区分大小写 |
~* | # 用于正则 uri 前, 表示 uri 包含正则表达式, 不区分大小写 |
@ | ”@“ 定义一个命名的 location,@定义的locaiton名字通常用在内部定向,例如error_page, try_files命令中。它的功能相似于编程中的goto。 |
Nginx有两层指令来匹配请求URI。第一个层次是server指令,它经过域名、ip和端口来作第一层级匹配,当找到匹配的server后就进入此server的location匹配。location的匹配并不彻底按照它们在配置文件中出现的顺序来匹配,请求URI会按以下规则跟server里配置的location匹配。java
简单来讲按这个规则 location 匹配命令的优先级从高到低依次为(序号越小优先级越高):nginx
1. location = /a {…} #精准匹配 2. location ^~ /a {…} #前缀匹配 3. location ~ /a.* {…} #正则匹配(区分大小写) 4. location ~* /a.* {…} #正则匹配(不区分大小写) 5. location /a {…} #最长前缀匹配,可是优先级低于正则匹配。 /a 和 ^~ /a 会冲突,报错 6. location / {} #任何没有匹配成功的,都会匹配这里处理
让咱们用一个例子来讲明上面的内容:web
# 请求: # / # /index.html # /documents/document.html # /images/1.gif # /documents/1.jpg location = / { # 只匹配 / 的查询. [ configuration A ] } # 能匹配成功: / location / { # 匹配任何请求,由于全部请求都是以”/"开始 # 可是更长字符匹配或者正则表达式匹配会优先匹配 [ configuration B ] } #能匹配成功:/index.html location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合之后,还要继续往下搜索/ # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条/ [ configuration C ] } # 能匹配成功:/documents/document.html location ~ /documents/ABC { # 匹配任何以 /documents/ 开头的地址,匹配符合之后,还要继续往下搜索/ # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条/ [ configuration CC ] } location ^~ /images/ { # 匹配任何以 /images/ 开头的地址,匹配符合之后,中止往下搜索正则,采用这一条。/ [ configuration D ] } # 能成功匹配:/images/1.gif location ~* \.(gif|jpg|jpeg)$ { # 匹配全部以 .gif、.jpg 或 .jpeg 结尾的请求,不区分大小写 # 然而,全部请求 /images/ 下的图片会被 [ config D ] 处理,由于 ^~ 到达不了这一条正则/ [ configuration E ] } # 能成功匹配:/documents/1.jpg location /images/ { # 字符匹配到 /images/,继续往下,会发现 ^~ 存在/ [ configuration F ] } location /images/abc { # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在/ # F与G的放置顺序是没有关系的/ [ configuration G ] } location ~ /images/abc/ { # 只有去掉 [ config D ] 才有效:先最长匹配 [ config G ] 开头的地址,继续往下搜索,匹配到这一条正则,采用/ [ configuration H ] } location ~* /js/.*/\.js
请求URI中问号后面的参数是不能在location中匹配到的,这些参数存储在$query_string变量中,能够用if来判断。
例如,对于参数中带有单引号’进行匹配而后重定向到错误页面。面试
/plus/list.php?tid=19&mid=1124’ if ( $query_string ~* “.*[;’<>].*” ){ return 404; }
这个不少解释不太准确,我有必要多说几句。
对于请求URI结尾是否带有/,通常的处理逻辑是带/表示访问目录,不带/表示访问文件,若是文件不存在也会去匹配目录。例如访问http://www.nginx.cn/images/和...://www.nginx.cn/images,前面的请求会匹配目录,后面的请求会先匹配文件,文件不存再匹配目录
对于locatioin中的URI来讲,若是URI的结尾带有/,而且location要执行的命令式是proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass、memcached_pass、grpc_pass之一。例如:正则表达式
location /images/ { proxy_pass http://www.redis.com.cn }
对于这种状况,nginx会作特殊处理,无论images命名的文件或目录存在不在,若是你访问http://www.nginx.cn/images会...://www.nginx.cn/images/。
因此若是你想这两种请求对应不一样的处理,就要明确增长不带/结尾的location配置。
location /images { proxy_pass http://www.rabbitmq.cn } location /images/ { proxy_pass http://www.redis.com.cn }
带有”@“的location是用来定义一个命名的location,这种location不参与请求匹配,通常用在内部定向。例如用在error_page, try_files命令中。它的功能相似于编程中的goto。
location /images { try_files $uri $uri/ @name; } location @name { … }
因此实际使用中,我的以为至少有三个匹配规则定义,以下:
直接匹配网站根,经过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
这里是直接转发给后端应用服务器了,也能够是一个静态首页。第一个必选规则:
location = / { proxy_pass http://tomcat:8080/index }
第二个必选规则是处理静态文件请求,这是nginx做为http服务器的强项,有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用:
location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; }
第三个规则就是通用规则,用来转发动态请求到后端应用服务器,非静态文件请求就默认是动态请求,本身根据实际把握,毕竟目前的一些框架的流行,带.php,.jsp后缀的状况不多了:
location / { proxy_pass http://tomcat:8080/ }
本文参考/引用:
Module ngx_http_core_module - nginx.org
nginx 中文文档 - nginx location匹配规则 - nginx.cn
nginx 一文完全读懂nginx中的location指令 - nginx.cn
nginx 这一篇就够了 - 哆啦A梦的猜测 - 掘金
nginx 配置location总结及rewrite规则写法 - seanlook - 思否
nginx平台初探(100%) — Nginx开发从入门到精通
推荐阅读:
【专题:JavaScript进阶之路】
JavaScript中各类源码实现(前端面试笔试必备)
深刻理解 ES6 Promise
前端性能优化小结(面试干货)
ES6 尾调用和尾递归
我是Cloudy,现居上海,年轻的前端攻城狮一枚,爱专研,爱技术,爱分享。
我的笔记,整理不易,感谢关注
、阅读
、点赞
和收藏
。
文章有任何问题欢迎你们指出,也欢迎你们一块儿交流各类前端问题!