当前位置: 首页 > 编程笔记 >

Nginx处理请求时的匹配规则详析

经嘉
2023-03-14
本文向大家介绍Nginx处理请求时的匹配规则详析,包括了Nginx处理请求时的匹配规则详析的使用技巧和注意事项,需要的朋友参考一下

nginx 在收到一条请求时将先通过 server_name 匹配一个 server, 然后使用 server 中的 location 继续匹配.

匹配 server_name

在 nginx 中, server_name 决定了当收到一个请求后哪一个 server 会被使用. nginx 会使用请求头中的 Host 字段与 server_name 进行匹配. 定义 server_name 时可以使用 完全名称、通配符名称、正则表达式名称, 它们的匹配顺序如下:

  • 完全匹配
  • 前通配符匹配, 即 *.example.org
  • 后通配符匹配, 即 mail.*
  • 正则表达式匹配

如果没有匹配到结果, 将会使用 default_server 进行处理, 如果没有定义, 则第一个定义的为 default_server. 使用三个简单的 server 作为例子, 让他们监听 80 端口, server_name 分别设置为 *.org、*.net、*.com:

server {
 listen 80;
 server_name example.org www.example.org;
 return 401;
}

server {
 listen 80;
 server_name example.net www.example.net;
 return 402;
}

server {
 listen 80;
 server_name example.com www.example.com;
 return 403;
}

在上面的配置中, 默认的服务器为 第一个, 随便访问一个不存在的 server 将会返回 401. 不过可以使用 default_server 手动设置一个默认主机, default_server 设置在 listen 字段, 如下:

server {
 listen 80 default_server;
 server_name example.net www.example.net;
}

之后再匹配时, 未匹配到将会使用这个 server.

禁止访问

如果想要禁止一个没有携带 Host 字段的请求, 可以定义如下 server:

server {
 listen 80;
 server_name "";
 return 444;
}

server_name 定义为空字符串, 如果 Host 字段为空或不存在, 将会匹配到这个 server, 然后返回 404 状态码.

Nginx 的444 状态比较特殊,如果返回 444 那么客户端将不会收到服务端返回的信息,就像是网站无法连接一样, 浏览器直接显示 502. 但是如果使用反向代理, 还是显示正常状态码

如果想要禁止访问不存在的主机, 可以这样定义:

server {
 listen 80 default_server;
 server_name _;
 return 444;
}

_ 在这里没有任何特别含义, 因为一个域名中不会出现 _, 所以不会与任何真实的域名相同, 使用其他非法字符是相同的道理.

同时匹配 IP 和 server_name

现在来看一下对于监听不同 IP 和不同 server_name 混合使用时是如何处理的:

server {
 listen 192.168.1.1:80;
 server_name example.org www.example.org;
}

server {
 listen 192.168.1.1:80;
 server_name example.net www.example.net;
}

server {
 listen 192.168.1.2:80;
 server_name example.com www.example.com;
}

在这个配置中, nginx 首先匹配 IP, 匹配到后再匹配它们的 server_name, 如果没有匹配到 server_name, 则使用到它们默认的 server. 举个例子, 如果一个域名为 www.example.com 的请求来自 192.168.1.1:80. 但是监听 192.168.1.1:80 的 server 只有两个, 这两个都不能匹配 www.example.com, 那么就使用这两个 server 中的默认主机, 由于没有使用 defualt_server 定义监听, 所以默认为第一个即 www.example.org 这个 server. 当然你可以定义 defualt_server:

server {
 listen 192.168.1.1:80;
 server_name example.org www.example.org;
}

server {
 listen 192.168.1.1:80 default_server;
 server_name example.net www.example.net;
}

server {
 listen 192.168.1.2:80 default_server;
 server_name example.com www.example.com;
}

匹配 location

在 nginx 匹配到一个 server 后, 就会通过 location 继续处理请求, 下面是一个示例:

server {
 listen 172.17.0.3:80;
 server_name _;

 location / {
 return 401;
 }

 location ~*\.(gif|jpg|png)$ {
 return 402;
 }
 
 location ~*\.(gif|jpg|png)$ {
 return 404;
 }

 location /api {
 return 403;
 }
}

nginx 首先会在所有的 location 中搜索 前缀进行匹配, 匹配到前缀后, 将按顺序匹配使用 正则表达式 定义的 location, 匹配到就结束, 如果没有匹配到, 则使用之前匹配到前缀的那个 location 进行处理, 下面是具体匹配的例子:

  • 一个 /x.gif 请求, 首先匹配到的前缀为 /, 然后使用剩下的 x.gif 跟 location 的正则去匹配, 先匹配到了 location ~*\.(gif|jpg|png)$, 返回 402.
  • 一个 /x.pdf 请求, 由于 x.pdf 无法被匹配到, 所以使用 location / 进行处理.
  • 一个 /api/x.gif, 首先匹配到前缀为 /api, 然后使用剩下的 x.gif 跟 location 的正则去匹配, 先匹配到了 location ~*\.(gif|jpg|png)$, 返回 402.
  • 一个 /api/x.pdf 请求, 由于 x.pdf 无法被匹配到, 所以使用 location /api 进行处理.

参考

  • How nginx processes a request
  • server names

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对小牛知识库的支持。

 类似资料:
  • 本文向大家介绍详解Nginx location 匹配规则,包括了详解Nginx location 匹配规则的使用技巧和注意事项,需要的朋友参考一下 语法规则 location [=|~|~*|^~] /uri/ { … } 模式 含义 location = /uri = 表示精确匹配,只有完全匹配上才能生效 location ^~ /uri ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 l

  • 本文向大家介绍简介Nginx中的location匹配规则,包括了简介Nginx中的location匹配规则的使用技巧和注意事项,需要的朋友参考一下 location匹配命令 ~      #波浪线表示执行一个正则匹配,区分大小写 ~*    #表示执行一个正则匹配,不区分大小写 ^~    #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录 =      #进行

  • 注意:本书中的 Service Mesh 章节已不再维护,请转到 istio-handbook 中浏览。 在上一节安装istio中我们创建BookInfo的示例,熟悉了Istio的基本功能,现在我们再来看一下istio的高级特性——配置请求的路由规则。 使用istio我们可以根据权重和HTTP headers来动态配置请求路由。 基于内容的路由 因为BookInfo示例部署了3个版本的评论微服务,

  • 基本模式匹配 一切从最基本的开始。模式,是正则表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如: ^once 这个模式包含一个特殊的字符^,表示该模式只匹配那些以once开头的字符串。例如该模式与字符串"once upon a time"匹配,与"There once was

  • 接收请求流程 (99%) http请求格式简介 (99%) 首先介绍一下rfc2616中定义的http请求基本格式: Request = Request-Line * (( general-header | request-header | entity-header ) CRLF) CRLF

  • 语法规则 location [=|~|~*|^~] /uri/ { … } 模式 含义 location = /uri = 表示精确匹配,只有完全匹配上才能生效 location ^~ /uri ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 location ~ pattern 开头表示区分大小写的正则匹配 location ~* pattern 开头表示不区分大小写的正则匹配 locat