侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

nginx 匹配规则简介

2023-11-02 星期四 / 0 评论 / 0 点赞 / 51 阅读 / 8879 字

server 匹配server 匹配通过 listen 和server_name 进行具体如下listen定义格式IP address/portlone IP address ( default po

server 匹配

server 匹配通过 listen 和server_name 进行具体如下

listen

定义格式

  • IP address/port
  • lone IP address ( default port 80)
  • lone port (every interface)
  • path to a Unix socket

匹配

  • translates
    • A block with no listen directive uses the value 0.0.0.0:80.
    • A block set to an IP address 111.111.111.111 with no port becomes 111.111.111.111:80
    • A block set to port 8888 with no IP address becomes 0.0.0.0:8888
  • match
    • 有IP 高于无IP
    • 端口必须匹配
  • 处理
    • 如果只有一个匹配则用它处理请求
    • 否则继续看 server_name
server {    listen 192.168.1.10;    . . .}server {    listen 80;    server_name example.com;    . . .}

server_name 会被忽略

server_name

  • server_name 与 Host 头信息 精确匹配
    • 如果有一个 则用它处理请求
    • 如果有多个则用第一个处理请求
    • 如果没有匹配继续下一个规则
  • server_name 与 Host 头信息 头通配符匹配 如 *.example.com
    • 如果有一个 则用它处理请求
    • 如果有多个则用匹配度最长的那个
    • 如果没有匹配继续下一个规则
  • server_name 与 Host 头信息 尾通配符匹配 如 www.example.*
    • 如果有一个 则用它处理请求
    • 如果有多个则用匹配度最长的那个
    • 如果没有匹配继续下一个规则
  • server_name 与 Host 头信息 正则匹配 如 server_name ~[a-z].example.*
    • 使用匹配到的第一个
    • 如果没有匹配继续下一个规则
  • server_name 与 Host 头信息 没有匹配
    • 使用 server_name 与 Host 头信息

示例

server {    listen 80;    server_name *.example.com;    . . .}server {    listen 80;    server_name host1.example.com;    . . .}

头信息为host1.example.com 使用第二个 server块,依据精确匹配

server {    listen 80;    server_name www.example.*;    . . .}server {    listen 80;    server_name *.example.org;}server {    listen 80;    server_name *.org;    . . .}

头信息为www.example.org 使用第二个 server块,依据头通配符匹配,二和三都匹配但三匹配长些

server {    listen 80;    server_name host1.example.com;    . . .}server {    listen 80;    server_name example.com;    . . .}server {    listen 80;    server_name www.example.*;    . . .}

头信息为www.example.com 使用第三个 server块,依据尾通配符匹配,

server {    listen 80;    server_name example.com;    . . .}server {    listen 80;    server_name ~^(www|host1).*/.example/.com$;    . . .}server {    listen 80;    server_name ~^(subdomain|set|www|host1).*/.example/.com$;    . . .}

头信息为www.example.com 使用第二个 server块,依据正则匹配,每二个server块是匹配到的第一个

location 匹配

定义语法

location 可以在 server 内或其它 location内定义

location optional_modifier location_match {    . . .}

location_match 与 请求URI 验证匹配, optional_modifier 可以有以下选择

  • (none) 什么都没有则使用前缀匹配,匹配请求URI的前部分与 location_match 是否匹配
  • = 等号匹配,请求URI 与 location_match 完全相同
  • ~ 区分大小写正则匹配
  • ~* 不区分大小写正则匹配
  • ^~ 如果是非正则的最佳匹配则不再使用正则匹配

示例

location /site {    . . .}

可以匹配 /site, /site/page1/index.html, /site/index.html

location = /page1 {    . . .}

只匹配 /page1, 匹配/page1/index.html

location ~ /.(jpe?g|png|gif|ico)$ {    . . .}

可匹配 /tortoise.jpg 匹配 /FLOWER.PNG

location ~* /.(jpe?g|png|gif|ico)$ {    . . .}

可匹配 /tortoise.jpg 匹配 /FLOWER.PNG

location ^~ /costumes {    . . .}

可匹配/costumes/ninja.html如果是最佳的非正则匹配则不再进行正则匹配,(不太明白,待研究)

location 匹配规则

  • 使用整个请求URI 与所有 前缀location 匹配

  • 如果有=修饰的location 与 请求URI 完全匹配,则用它处理请求(end)

  • 如果没有=修饰的location 与 请求URI 完全匹配, 则查找最长匹配的 前缀 location

    • 如果这个最长匹配的 前缀 location 包含^~, 则用它处理请求(end)
    • 如果这个最长匹配的 前缀 location 包含^~,则保存此条,继续下一个规则
  • 开始匹配正则 location(包括 区分大小写和不区分大小写), 如果上一规则保存的 前缀 location与任意一个正则 location 匹配则将其放在最前, 然后使用第一个正则 location 处理请求(end)

  • 如果没正则 location 匹配,则使用上一规则保存的 前缀 location 处理请求(end)

因为正则匹配 使用第一个匹配结果,所有正则 location 是有重要意义的

  • 如果都没匹配到是不是就 404了?

location 跳转

可能引起跳转的指令

  • index
  • try_files
  • rewrite
  • error_page
index
index index.html;location = /exact {    . . .}location / {    . . .}

请求/exact, 但要处理这个请求,需要index 指令介入,从而导致跳转到第二个location 块(待验证)如果确实是访问 /exact,可修改配置如下

location = /exact {    index nothing_will_match;    autoindex on;}location  / {    . . .}

(待验证)

try_files
root /var/www/main;location / {    try_files $uri $uri.html $uri/ /fallback/index.html;}location /fallback {    root /var/www/another;}

如果请求为/blahblah, 则第一个location 处理此请求,尝试查找 /var/www/main 目录下有没有 blahblah 文件,如果没找到再尝试查找 目录下有没有blahblah.html 文件, 如果没有再尝试查找 目录下有没有 blahblah/ 目录, 如果没有重定向到/fallback/index.html

第二个 location 处理这个请求,并访问 /var/www/another/fallback/index.html文件

rewrite
root /var/www/main;location / {    rewrite ^/rewriteme/(.*)$ /$1 last;    try_files $uri $uri.html $uri/ /fallback/index.html;}location /fallback {    root /var/www/another;}

如果请求为 /rewriteme/hello, 则第一个location 处理此请求;rewrite将请求重写为/hello, 再次由 第一个location 处理此请求;此时由 try_files 如上一示例一样处理

而如果请求为 /rewriteme/fallback/hello, 则先由第一个location 处理此请求;rewrite将请求重写为/fallback/hello, 再次由 第二个location 处理此请求;

redirect

向浏览器发送重定向指令return 301、302 new_urirewrite xxx redirect/permanent;这个批量的location都是明确的这样会发起一个新的请求

error_page

root /var/www/main;location / {    error_page 404 /another/whoops.html;}location /another {    root /var/www;}

如果请求 /another,则会由第一个处理,如果请求的文件没有找到则使用第二个并最终访问 /var/www/another/whoops.html 文件

参考

翻译整理自 https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithmshttps://www.ruby-forum.com/topic/4422812#1136698

广告 广告

评论区