nginx try_files流程解析
创始人
2024-02-01 14:22:32

前端部署单页应用时在nginx上经常用到try_files指令,而对于try_files并不知道其所以然,所以花时间整理总结如下。

Syntax: try_files file … uri;
try_files file … =code;
Default: —
Context: server, location

根据root和alias指令提供的值按照try_files指令值的顺序查找对应文件是否存在。可以通过以斜杠结(/)尾的文件名让try_files查找文件夹是否存在(例如:“$uri/”)。try_files指令提供的file都不存在那么就会发起内部重定向到最后的值uri。如果可以找到,以找到的第一个file作为条件继续处理当前请求。

上面的描述没有错,但是不够具体,刚看这个描述我有如下问题:

  1. 对于file和uri try_files有什么不同的处理?
  2. try_files的处理流程在nginx中具体是什么样的?
  3. 查找到文件和文件之后呢?
  4. 什么是内部重定向?

准备工作

  1. 开启nginx的debug模式
  • 确保 nginx -V 输出有 configure arguments: --with-debug。如果没有需要重新编译安装ngxin,具体方法借助搜索引擎吧。

  • 在http模块下添加配置:

      http {# 设置错误日志地址和日志级别为debugerror_log path/to/log/file debug;}
    
  1. 准备验证环境
  • 准备网站根目录 /path/to/www/
  • 添加测试nginx服务:
    server {listen 8080;root /path/to/www/;location / {try_files /helloworld.html /hello/ /internalRedirect;}location /internalRedirect {return 200 "internalRedirect";}
    }
    
  1. 准备知识
    nginx 配置文件执行是分为11个阶段按照顺序执行的,try_files涉及到的阶段有find-config、try_files和content这三个阶段,server-rewrite、rewrite、post-write等剩余阶段省略。

    find-config阶段主要根据请求的uri在nginx文件中寻找匹配的location块。

    try_files阶段主要执行try_files指令。

    content阶段上面的nginx服务只涉及到默认的模块,nginx_index、nginx_autoindex和nginx_static。

try_files指令解析

  1. 当请求匹配中 location / 时,try_files会去找文件 /path/to/www/helloworld.html没找到会继续找/path/to/www/hello文件夹,都没找到,最后会内部重定向到 /internalRedirect。

    curl http://localhost:8080/
    

    返回:

    internalRedirect
    

    截取部分debug日志文件。

    [debug] 17945#0: *2 trying to use file: "/helloworld.html" "/path/to/www/helloworld.html"
    [debug] 17945#0: *2 trying to use dir: "/hello" "/path/to/www/hello"
    [debug] 17945#0: *2 trying to use file: "/internalRedirect" "/path/to/www/internalRedirect"
    [debug] 17945#0: *2 internal redirect: "/internalRedirect?"
    [debug] 17945#0: *2 rewrite phase: 1
    [debug] 17945#0: *2 test location: "/"
    [debug] 17945#0: *2 test location: "internalRedirect"
    [debug] 17945#0: *2 using configuration "/internalRedirect"
    

    nginx执行顺序是先执行findConfig匹配和$uri合适location块配置,才会执行try_files指令,当try_files使用内部重定向的时候,请求的处理流程会被回退到findConfig阶段重新使用/internalRedirect重新匹配location。这个重定向和外部重定向http的301不一样,它并不会引起浏览器地址栏的url的修改,所以被称为内部重定向。

  2. 当找到 /helloworld 之后try_files指令会重写uri的值,当执行到content阶段后会依据新的uri的值,当执行到content阶段后会依据新的uri的值,当执行到content阶段后会依据新的uri值获取对应的静态文件。

  • 在/path/to/www/文件夹下添加helloworld.html文件,其内容是hello world。

  • 在ngxin配置中添加
    add_header header_uri $uri;

    curl -i http://localhost:8080/  # -i 会展示响应头
    

    返回:

    HTTP/1.1 200 OK
    ...
    header_uri: /helloworld.htmlhello world
    

    截取部分log文件日志:

    [debug] 18875#0: *1 trying to use file: "/helloworld.html" "/path/to/www/helloworld.html"
    [debug] 18875#0: *1 try file uri: "/helloworld.html"
    ...
    [debug] 18875#0: *1 http filename: "/path/to/www/helloworld.html"
    
  1. 当文件夹hello存在,try_file会将$uri修改为 /hello 接着给content阶段的模块处理。
  • 删除上一步骤的helloworld.html文件。

    curl -i http://localhost:8080/  # -i 会展示响应头
    

    返回:

    HTTP/1.1 301 Moved Permanently
    ...
    header_uri: /hello
    301 Moved Permanently
    
    

    301 Moved Permanently


    nginx/1.23.0

    截取部分log文件日志:

    [debug] 18875#0: *2 trying to use file: "/helloworld.html" "/Users/zhou/nginx_web/helloworld.html"
    [debug] 18875#0: *2 trying to use dir: "/hello" "/Users/zhou/nginx_web/hello"
    [debug] 18875#0: *2 try file uri: "/hello"
    [debug] 18875#0: *2 http filename: "/Users/zhou/nginx_web/hello"
    [debug] 18875#0: *2 http static fd: -1
    [debug] 18875#0: *2 http dir
    [debug] 18875#0: *2 http finalize request: 301, "/hello?" a:1, c:1
    

    为什么try_files寻找文件夹的时候需要把指令值/hello/改成/hello?我理解末尾的斜杠只是表示try_files这个名字是一个文件夹名,所以找的时候把末尾的斜杠去掉了,如果想要$uri被赋值的时候带上末尾的斜杠可以 try_files /helloworld.html /hello// /internalRedirect,可以给他多加一个斜杠。

参考

agentzh 的 Nginx 教程(版本 2020.03.19)

Nginx文档try_files指令

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...