0


nginx(八十二)try_files、content阶段深入探究

一 try_files、content阶段、outfilter再探

① 哪些人适合阅读

适合: 拿nginx作为'静态服务器'网站'前端'人员必备,后端程序员可以'选择性的忽略'

备注: 该篇一个'阶段性'的总结,后续'不再'探讨该部分

补充: 按照'try_files'、'content'阶段的'模块指令'的'执行顺序'讲解

强调: 本文'不具有实际意义',只是试图从'应用层现象'来解读运行机制

① 相关博客系列

备注:学习要有一个'过程',不可能'一蹴而就',下面的博客记录了我的'成长史',某一个时刻就'豁然开朗'

root、alias、index、try_files关系指令再探

precontent阶段的模块学习 核心try_files指令

content阶段index和autoindex模块学习

content阶段static模块学习

filter模块处理

章亦春大神的nginx权威参考

③ content阶段涉及模块指令处理顺序

1) 本次'只探讨'try-files、content阶段,附加'filter'系列模块

2) content 阶段是'所有请求处理阶段中'最为'重要'的一个

特点: 因为运行在'这个阶段'配置指令一般都肩负着生成"内容(content)"并输出'HTTP 响应'的使命

强调: 当存在"content handler 内容处理程序"的指令时,'静态资源服务模块'并'不会'起作用

3) 绝大多数 'nginx 模块'在向 'content 阶段' 主动'注册配置指令'时

重点: 本质上是在'当前的 location 配置块'中'注册'所谓的"内容处理程序(content handler)"

常见: ngx_echo模块 ["echo指令"]、ngx_proxy ["proxy_pass"]

强调: 
 
  [1]、每一个 location 只能有一个"内容处理程序"

  [2]、当在 location 中同时'使用多个模块'的 content 阶段指令时

  [3]、只有'其中一个模块'能成功注册"内容处理程序"

4) 如果location中'没有'使用在 content 阶段'注册的'模块指令,也即没有'content handler'

  [1]、处理权便'自动'落到了在 content 阶段"垫底"的那 '3个'静态资源服务模块

  [2]、首先运行的 'ngx_index' 和 'ngx_autoindex' 模块

  特点: 如果'当前请求的uri'是'以 / 结尾',就会使用对应'index'和'autoindex'指令

  [3]、否则直接'弃权',将处理权转给了最后运行的 'ngx_static' 模块

  特点: ngx_static 模块根据 '(root|alias) 指令'将'请求$uri' 映射为'文件系统'路径 

  备注: 这个模块主要实现'服务静态文件'的功能,也是nginx作为'web服务器'的核心

  [4]、在确认'磁盘中'文件'存在'后,将它们的内容分别作为响应体输出,并自动设置'相应'响应头

  备注: 如果'文件不存在',则返回'404',这才是'资源不存在'

5) 有的'模块'指令是'默认提供的',有的模块'没有指定',则'跳过'这个模块

备注:有些指令作用'对应地方'也能改变'11个阶段'

6) nginx '变量'则经常扮演着在'指令间'乃至'模块间'传递'小份数据'的角色

7) ngx_index、ngx_autoindex、ngx_static模块执行'顺序'和'处理特点'对比:

  [1]、ngx_index 和 ngx_autoindex 模块都'只会'作用于那些$uri以'/结尾'的请求

  [2]、对于'不以/结尾的请求'则会直接'忽略',同时把处理权移交给'ngx_static 模块'

  [3]、而'ngx_static 模块'则刚好相反,直接'忽略'那些 $uri 以 '/ 结尾'的请求

    1、'真正'把相应的'内容(正常|异常)'发送出去,还是得靠这个 'ngx_static 模块'来完成

    2、所作的操作:即把'该文件的内容'作为响应体数据输出,并设置相应的'响应头'

④ try_files指令再探

知识铺垫

1)precontent'阶段':

  特点: 这个阶段'专门'用于实现标准配置指令'try_files'的功能,'不'支持nginx模块注册处理程序

  默认: '没有'指定'try_files',所以'precontent'阶段默认'不存在'

2) 语法: try_files file1 file2 ... '(uri|=code)'

  本文: 对'try_files'各种行为的探究

  备注: 支持'@location'这种'uri'

  补充: 这里的'file1 ,file(n-1)'等指的是'资源对象(file|directory)'

  最佳实践: try_files $uri $uri/ @wzj;

3) 细节点:'try_files'通过'alias|root'、'$uri'、'location'来判断文件系统对象是否存在

4) 探究案例:

 [1]、文件资源'存在'

 [2]、文件'不'存在,'目录资源'存在

 [3]、前'N-1'个都不存在,'uri|=code'进行匹配

 备注: 读者应该'注意'各个案例的'前提条件[上下文]'

 观察: 'debug日志'输出,并'分析'

案例1:try_files file '文件'存在时,使用'content handler'和'默认content'行为'对比'实验

+++++++++++++++++++++ "分割线" +++++++++++++++++++++

案例2: try_files file '目录资源对象'存在时

备注: 使用'content handler'和'默认content'行为'对比'实验

++++++++++++++++ "分析过程" ++++++++++++++++

1) nginx 在 try-files 阶段发现'第一个参数 /wzj' 对应的'文件 file'不存在

2) 就会转向检查'第二个参数 /wzj/'对应的'文件系统对象'

3) 由于'此目录'存在,并且'$uri'不是以'/'结尾的

细节: 此时nginx就会把当前请求'uri 改写'为第'二个参数的值(不带末尾/)',即$uri为'/wzj'

注意: try_files '原始'参数值是 /wzj/,但 try_files 会自动'去除末尾'的'斜杠/'字符

4) 由于是一个'目录'资源,nginx会进行'301重定向',并返回'Location: $uri/'

过程:此时$uri不是以'/'结尾,所以'index、autoindex'指令对应的模块不起作用,ngx_static处理

强调:

  [1]、实际'try_files 非internal命中',还是会向下'处理','index、autoindex'被忽略

  [2]、ngx_static会不是以'/'结尾的'$uri'映射的'文件'或'目录'做不同处理

备注: 理解上可以认为'约等于' 'rewrite ^ $uri/ permanent;'这种'相对'重定向

5) 接着'基于新的url',从客户端重新发起'重定向'请求

6) 在'try_files'由于'第二个参数 /wzj/'匹配判断是'目录',并且$uri是以'/'结尾

7) 此时转交到'ngx_index'模块,由于'此时映射的系统文件不存在',继续'ngx_autoindex'模块

8) 由于上述处理'/'结尾的'$uri'的两个模块没作用,'ngx_static'模块又处理不了以'/'结尾$uri

9) 此时返回'默认'内置的'403'的页面

说明: 下面的是'重定向'请求的'error.log'日志

备注: 同时给出了'$uri以/'结尾,并且'try_files directory'匹配的场景

对比实验: 基于'案例2',前提'条件不变',修改'相对重定向'的策略,观察结果

双层nginx 转发下的 try_files 指令 301 返回错误的 location 地址 try_files导致301

对比实验: 基于'案例2',前提'条件不变',使用'content handler'

强调: 

  1) 即使是'try_files $uri/'判断'目录资源存在',也会继续进行'content'阶段的处理

  2) 所不同的是经过模块注册的'content handler',还是'nginx内置默认的content'

对比实验: 基于'案例2',前提'条件不变',基于'Location 301'使用'exact location'

案例3: 最后一个'uri'起作用

备注: 

  1) '普通uri'         --> '$args'会丢失     -->   'rewrite ^ /java? last'

  2) '命名location'    --> '$args'不会丢失    -->  'rewrite ^ /java last'

1)  try_files 指令本质上只是'有条件'地改写当前'请求的 URI'

2)  这里说的"条件"其实就是文件系统上的'对象(file|directory)是否存在'

3)  当"条件"都不满足时,它就会无条件地发起一个指定的"内部跳转"

备注: 除了无条件地发起'内部跳转'之外, try_files指令还支持直接返回指定状态码'HTTP 错误页'

案例4: 最后一个'=code'起作用,观察'add_header'行为

说明: 从语义上来说,一般使用'404'返回指定状态码的 'HTTP 错误页'

思考: try_files可以指定'哪些'状态码? 

备注: 自己尝试过'401'、'301(没有Location)'、使用'20(0|6)'不报错但'阻塞'、'204'是ok

遗留: 如果指定'error_page' 相同'状态码'是否能补获?  --> "会"

⑤ index指令再探

思考1: 什么场景会触发'index'指令的执行?  --> 假定在一个'location'内

  前提: 没有其它模块注册'content handler',并且'$request_uri'以'/'结尾

  [1]、'$request_uri'中以'/'结尾,但'没有'指定'try_files'

    补充: 'try_files directory'映射系统资源'存在',虽然会改变'$uri',但是会去掉末尾的'/'

  强调: 上述是'触发 index'的充分不必要条件,并不意味着'index ...'能命中,只是'有机会'执行

  附加: ngx_index 和 ngx_autoindex 模块都只会作用于那些 '$request_uri以/结尾'的请求

思考2: index指令是'如何执行'的?

  [1]、依次判定'指定的首页文件'是否存在?  --> 基于'(root|alias)'判定

  [2]、如果全都'不存在'则进行'ngx_autoindex'模块,要不返回'文件列表',要么返回'403'

  [3]、如果存在'指定的首页文件',则基于该'$uri$index_value'发起'internal'内部跳转

    备注: 此时index 后续的'value'不再执行,并且'该次内部请求'的'后续阶段'也不再执行

问题1: 为什么我配置的'index'首页却不生效?

  原因: 

       1) 由于'location'优先级原因,进不到之前的'location'中导致异常

       2) index 指定的'首页'

  场景: 'ngx_index 模块'主要用于在'文件系统目录中'自动查找'指定的首页'文件

  思考: 如何才能真正'设置首页'与我们的'预期相符'呢?

案例:

  1)案例1:'index .. 匹配不上',观察行为   --> 才有可能轮到'autoindex'指令执行

  2)案例2:'index .. 匹配上',只使用一个'location'观察行为

  3)案例3:'index .. 匹配上','定义新的 location',观察匹配行为

merge_slashes

1) 'try_files directory[/kafka/]' 改变了'$uri',同时导致301 'Location $uri/'

2) 继续发起请求'/kafka/'进行'index index.html'匹配,'文件'存在

3) index改变'$uri'为'/kafka/index.html',此时不以'/'结尾,autoindex即使配置也无法处理

4) 最后交给'ngx_static'处理

与'案例1'的对比实验: 由于'location的'优先级,导致非预期的'首页'

与'案例1'的对比实验: index 配置的值以'/'结尾,同时'autonindex on'开启观察

 1) 第一次'index /wzj/' 查找系统资源为'目录'

   强调: 只有'index file'匹配,才会改变'$uri'

 2) 导致'$uri'变为'/kafka/wzj/',继续进行'internal'重定向行为

   官方: 只有'index (file|dir)'不存在,才会执行'autoindex',index'优先级'高
   
   大白话: 只要'index (file|dir)'匹配上,永远不会执行'autoindex'
       
 3) 通过'add_header或error.log'观察

   说明: 'index dir'场景

与上述的'对比'实验: 配置文件'不变',改变'前提条件',请求url'不变'

说明: 注意'autoindex on'执行的'条件',是一个'备胎'

标签: nginx try_files content

本文转载自: https://blog.csdn.net/wzj_110/article/details/131013665
版权归原作者 wzj_110 所有, 如有侵权,请联系我们删除。

“nginx(八十二)try_files、content阶段深入探究”的评论:

还没有评论