【Nginx12】Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

news2024/9/23 17:22:52

Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

浏览器缓存在 Nginx 的 HTTP 核心模块中其实只有两个简单的配置,这一块也是 HTTP 的基础知识。之前我们就一直在强调,学习 Nginx 需要的就是各种网络相关的基础知识,其中更重要的就是 HTTP 和 TCP 相关的内容。另外一个 try_files 配置指令也是 Nginx 中非常常用的一个指令,用于找不到指定的路径文件时,可以去按顺序查找备用的一些文件路径,非常实用。

浏览器缓存

在 HTTP 协议中,有许多和浏览器缓存有关的选项,而在 Nginx 的核心配置中,也有两个与之相关的配置。

if_modified_since

if_modified_since 是由浏览器发送的,让服务端来判断返回 200 还是 304 ,在 Nginx 中,它用于指定响应的修改时间与 if_modified_since 请求头的比较方法。

if_modified_since off | exact | before;

默认值是 exact ,每个选项分别代表:

  • off 忽略 “If-Modified-Since” 请求头 (0.7.34)

  • exact 精确匹配

  • before 响应的修改时间小于等于 “If-Modified-Since” 请求头指定的时间

etag

etag 是由服务器端生成的,客户端通过发送 If-Match 或者 If-None-Match 这个条件判断请求来验证资源是否修改。Nginx 中,这个配置可以开启或关闭为静态文件自动计算 “ETag” 响应头。

etag on | off;

它的默认值是 on 。

测试

正常情况下,我们第一次打开某个静态页面,是没有 if_modified_since 的,服务端会返回 ETag 和 Last-Modified 以及 200 状态码。

81e22c4e25260e5a61b809e047343324.png

然后第二次请求的时候,浏览器就会带上 if_modified_since ,服务端会返回 304 表示使用本地缓存就可以了。

05306e894d83893664f6356a0670986c.png

这是在默认情况下。现在我们修改 Nginx 的配置,先将 if_modified_since 设置为 off ,然后强刷页面之后再进行普通刷新 ,会发现不管是强刷还是普通刷新,响应头和请求虽然没有什么变化,但服务端都只会返回 200 了。也就是说,服务端不会去比较浏览器发送过来的 if_modified_since 值来判断是否返回 304 。

接下来测试 etag ,这个就麻烦一点,首先,我们要将 if_modified_since 设置为 before ,意思就是访问的静态资源文件的修改时间小于当前浏览器提供的 If-Modified-Since 时,才返回 200 。这样的话,如果我们手动修改文件的时间,将时间修改到当前时间之后很长的一段时间,那么就可以让浏览器在非强刷的状态下一直返回 304 。

touch -m -d "2023-09-08 12:23:04" /usr/local/nginx/html/aaa.html

默认 etag 为 on 的情况下,你再次修改文件的时间,依然会正常返回一次 200 。这就是 etag 的作用,它是根据文件一些属性进行综合 Hash 从而返回一个值,客户端保存上回的 etag 值后传送到服务端进行比对。而如果现在你将 etag 设置为 off 的话,那么再次请求就不会有 Etag 响应头返回了,这时修改文件的时间,甚至是修改文件的内容(注意修改内容后还要手动修改一下文件的修改时间,否则 if_modified_since 就会生效返回 200 了),后面的请求也将一直会是 304 (非强刷)。

ps.浏览器强刷其实就是浏览器不带任何和 HTTP 缓存有关的请求头进行一次请求访问。

Etag 最主要解决的其实是 if_modified_since 的一些缺点,比如说有些时候可能我们只是周期性地修改一下文件,但文件内容不发生变化(只是文件修改时间变动),这时其实可以不用重新 200 响应的。另外还有 if_modified_since 只支持到秒级,而 Etag 的 Hash 变化是跟随文件变动的,因此它的粒度更细一些。还有一种情况就是某些服务器不能精确的得到文件的最后修改时间,这也会导致 if_modified_since 产生问题,更典型的就是客户端时间和服务器时间不同步,比如有的人的电脑可能时间一直就是错的。

这一块的内容是 HTTP 的基础知识,而且写文字也不太好描述怎么测试,大家可以关注下后期的视频哈,在视频中咱们再好好演示。

try_files

按指定顺序检查文件是否存在,并且使用第一个找到的文件来处理请求,那么处理过程就是在当前上下文环境中进行的。

try_files file ... uri;
try_files file ... =code;

其实就是我们不确定用户访问的路径或者文件存不存在,这时可以按照 try_files 指定的顺序来展示指定的 URI ,通常它都会和 $uri 变量一起搭配使用,$uri 变量就是当前访问的 location 地址。说白了,就是给请求的链接准备好备胎,能够为用户带来更优良的用户体验。

文件路径是根据 root 指令和 alias 指令,将 file 参数拼接而成。 可以在名字尾部添加斜线以检查目录是否存在,比如“$uri/”。 如果找不到任何文件,将按最后一个参数指定的uri进行内部跳转。 比如:

location /tf1/ {
 try_files $uri /50x.php;
}

现在试试访问 /tf1 ,会发现显示的是 50x.php 的内容,如果 /tf1 下面有页面的话,那么直接访问就可以查看到指定的页面。这种感觉是不是有点像 error_page ,其实上面的内容就相当于是下面这样的代码。

location /tf1/ {
 error_page 404 /50x.php;
}

$uri 变量表示的是规范以后的 URI ,也就是拼接请求之后完整的 URI 路径。不过这个变量的值可能会随着请求的处理过程而改变,比如,当进行内部跳转时,或者使用默认页文件时。

这下就看出来了吧,try_files 按顺序,如果第一个 $uri 找到文件了,就直接使用这个文件,如果没找到,就找第二个,依次类推,我们也可以一直向后多写几个 uri ,直到有一个能够找到对应的文件。

location /tf2/ {
 try_files $uri /tf2/1.html /tf2/2.html;
}

在 tf2 目录下,建立了两个文件,然后访问 /tf2 ,会显示 1.html 的内容,访问 /tf2/2.html ,正常显示 2.html 的内容,按顺序来说 $uri 是第一位的,后面的顺序哪个先找到就按哪个来。因此,除了指定访问 /tf2/2.html 之外,其它链接都会打开 1.html (如果有 404 的 error_page 设置,则直接走 404 的)。那么如果是跳转 uri 呢?比如我们跳转到 php 的 URI 上。

location /tf3/ {
 try_files $uri /50x.php /404.php;
}

随便访问 /tf3 或者目录中的任意不存在的路径,我这里会弹出下载,查看请求 Content-Type 会变成 application/octet-stream ,下载的文件是 php 的源码。注意,这里是个坑点,不要在静态配置中进行这样的 try_files 。换成带 PHP 相关配置的再试试。

location /tf4/ {
 try_files $uri /tf4/1.php /1.php =404;
 
 fastcgi_pass unix:/var/sock/php-fpm/www.sock;
 fastcgi_index  index.php;
 fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
 include        fastcgi_params;
}

现在访问 /tf4 会显示到最外面那个我们之前测试的时候打印所有 $_SERVER 内容的 1.php 页面。如果我们创建 tf4 目录,并且添加一个 1.php ,并打印 echo "this is tf4/1.php."; 那么,再次刷新,页面就会展示 this is tf4/1.php. 。这样才能正常的显示 php 。不过我们直接用静态配置去 try_files 动态文件也有别的方法,就是使用命名 location 。

location /tf5/ {
   try_files $uri @tf5php;
}
location @tf5php {
  root html;
  fastcgi_pass unix:/var/sock/php-fpm/www.sock;
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME  $document_root/tf5php/index.php;
  include        fastcgi_params;
}

访问 /tf5 或者 /tf5/xxx.html ,都会打开 tf5php 目录下的 index.php 文件。注意,这里演示的是从 静态 文件到 php 文件,如果是 /tf5/xxx.php 则会被之前我们配置过的 ~ \.php 的配置拿走,不会走到这边来。

我们再来看看响应码的问题。

location /tf6/ {
  try_files $uri $uri/ /xxx.html  =401;
}

这一段表示的是如果前面 uri... 部分都没有匹配到,那么就会返回 401 的状态码。大家可以自己试一下访问 /tf6 下的任意文件,最后返回的都是 401 状态。

好了,我们再来看一下 Laravel 文档中给的一个 Nginx 配置,其中有一段内容是大部分 PHP 应用在部署的时候也都会要求写上的。

location / {
  try_files $uri $uri/ /index.php?$query_string;
 }

在全局的 location 中,访问 uri 页面或者 uri/ 目录,找不到文件的话,会转给 /index.php,并且把请求行的 GET 参数转给 /index.php 文件。通常现代化的框架都是单一入口,index.php 总是可以接收请求的,如果确实还是找不到,也将由 PHP 应用来进行对应的 404 或者 500 处理。

另外,try_files 还可以做一件非常常见的事,就是显示默认图片。

location /images/ {
    try_files $uri /images/default.gif;
}

正常的图片路径找不到图片了,就使用默认的图片来代替,这也是很多网站的基本需求。

总结

今天的内容不难吧,加起来就是三个配置项,不过我们做了很多的测试。缓存对于现代化的 Web 开发来说非常重要,而 HTTP 缓存则是最前端的面向客户一级的缓存。对于静态资源来说,有着非常重要的作用,可以大大减少服务器的压力。而 try_files 的灵活则为我们带来了更多的特色功能,类似于默认图片这类的配置都能够非常简单方便。

不过估计大家平常可能对这几个指令用得也并不多,毕竟缓存那两个都有默认值,我们保持默认就好了。而 try_files 通常最多的就是用在上文所说的全局路径的处理上,是使用 Laravel 时必备的一个配置。但是,通过今天的学习,相信咱们将来在需要的时候,也能马上想起来这些配置指令的用法,能够更加灵活自如的运用它们。学习,就是这样一步一步的不断积累,一次一次的不停实践。

参考文档:

http://nginx.org/en/docs/http/ngx_http_core_module.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/801441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端程序员入门:先学Vue3还是Vue2?

一、前言 对于新手来说,学习Vue.js框架时往往会有这样一个疑问:应该先学习Vue2还是直接学习Vue3?在回答这个问题之前,我们先简单介绍一下Vue.js框架。 Vue.js是一个轻量级的MVVM(Model-View-ViewModel)框架,它以数据驱…

数字世界未来十年面貌展望

2023年,数字技术已经深刻改变了我们的生活和社会,而未来十年数字世界的面貌将会更加令人瞩目。从人工智能到区块链,从虚拟现实到5G,各种科技将继续发展演进,给我们带来更多令人兴奋的可能性。以下是对数字世界未来十年…

交换机之HOL拥塞

队首阻塞(Head of Line Blocking, HOL)是一种出现在缓存式通信网络交换中的一种现象,其交换结构通常由缓存式FIFO输入端、交换结构(Switch Fabric)、FIFO输出端构成。 HOL阻塞用一个现实生活中的例子说明,就如同你在一条单车道的马路上右转,…

人机交互与人机混合智能的区别

人机交互和人机融合智能是两个相关但不完全相同的概念: 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面,以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计,旨…

如何找回删除的文件?文件恢复,3招就行!

“昨天不小心把我的毕业资料删除了,因为改了很多版,删除的时候没想到把正确的版本删除了,错误的版本还在!这种情况应该怎么办呢?怎样才能找回我删除的文件呀?” 对于一些比较重要的文件,不小心删…

【C++初阶】C++基础(上)——C++关键字、命名空间、C++输入输出、缺省参数、函数重载

目录 1. C关键字 2. 命名空间 2.1 命名空间的定义 2.2 命名空间的使用 3. C输入&输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C支持函数重载的原理——名字修饰(name Mingling) 5.3 extern &…

围棋基础知识

1、气 1.1星位位置 1.2天元位置 1.3 气的位置 2、禁入点 白棋里面的位置就是禁入点,也可以称为没有气的位置可以称为禁入点 破解之法: 在于将白棋全部围住,下一步为围住之策,即可。 3、死棋和活棋 3.1活棋 3.2 死棋 白棋的样…

探寻数据服务的本质:API之外的可能性

数据服务在数据建设中发挥着重要的作用。数据服务到底啥样? 是不是只对外提供一个API? 这么简单? 而我希望你能在学完这部分内容之后,真正掌握数据服务的产品功能设计和系统架构设计。因为这会对你设计一个数据服务,或…

青少年护眼灯哪个好?2023全新五款台灯推荐

国内儿童青少年的视力健康问题越来越突出,甚至许多孩子年纪非常小就已经近视了,所以许多老师以及眼科医生都和家长们强调护眼台灯的重要性。不过,护眼台灯虽好,但在选购时也要注意那些无法护眼的不专业品牌,许多产品有…

ICC2如何计算Gate Count?

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?知识星球入口 我们认为gate count等于standard cell(非physical only)总面积 / 最小驱动二输入与非门面积。 ICC2没有专门的命令去报告gate count,只能自己计算,使用report_d…

MySQL数据库——DDL基本操作

文章目录 前言数据库操作查看已存在的所有数据库创建数据库选中数据库删除数据库修改数据库编码 表操作创建表显示创建表时的语句显示表结构删除表修改表的结构增加列修改列删除列 修改表名 前言 DDL 操作是与数据库结构相关的操作,它们不涉及实际的数据操作&#…

B2B企业如何选择CRM系统?

CRM软件的优势在于简化业务流程,实现企业的降本增效。越来越多的B2B企业通过CRM为业务赋能,B2B企业如何快速找到适合公司业务的CRM系统?总的来说就是根据企业自身业务而量身打造的一套系统。 1.整理业务需求 B2B企业首先要考虑是业务痛点&a…

易基因:m6A-seq等揭示RBM33参与调控m6A去甲基化酶ALKBH5活性及其底物选择性|科研进展

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 RNA结合蛋白(RNA-binding protein,RBP)是一类结构和功能多样化的蛋白质,参与多种生物过程。越来越多的证据表明,RBP通过调控编…

意外:WPS编程新工具,不用编程,excel用户:可以不用VBA啦

来来来,拓宽一下视野! 别总以为excel和WPS只能用VBA编程,也别总是想着ACCESS这些老生常谈的工具。其实对于电子表格高级用户来讲,不会VBA,不用ACCESS,也一样可以解决复杂问题或者高级应用。 尤其是WPS用户…

C++多线程编程(第三章 利用栈特性自动释放锁RALL,锁管理器、控制器)

1、什么是RALL,手动代码实现 RALL(resource Acquisition Is Initialization )C 之父Bjarne Stroustrup 提出; 使用局部对象来管理资源的技术称为资源获取即初始化;它的生命周期是由操作系统来管理的,无需人…

Hive分区分桶

分区 分区概念 在逻辑上分区表与未分区表没有区别,在物理上分区表会将数据按照分区键的列值存储在表目录的子目录中,目录名“分区键键值”。其中需要注意的是分区键的值不一定要基于表的某一列(字段),它可以指定任意…

ubuntu软件:录制视频和截图工具,压缩视频

1. 自带录制视频工具; 使用方式: 无需下载 开始录屏/结束录屏:Ctrl Alt Shift r 当看到 Ubuntu 桌面的右上方多了一个红色的小圆点,代表正在录制 注意: 录屏默认的时长30秒,超时会自动结束&#xff01…

Postman如何导出接口的几种方法

本文主要介绍了Postman如何导出接口的几种方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 前言: 我的文章还是一贯的作风,简确用风格(简单确实有用)&am…

无涯教程-jQuery - serialize( )方法函数

serialize()方法将一组输入元素序列化为数据字符串。 serialize( ) - 语法 $.serialize( ) serialize( ) - 示例 假设无涯教程在serialize.php文件中具有以下PHP内容- <?php if( $_REQUEST["name"] ) {$name$_REQUEST[name];echo "Welcome ". $na…

JavaScript小结测试

题目 有两个体操队&#xff0c;海豚队和考拉队。他们互相竞争3次。平均得分最高的赢家将获得奖杯! 利用下面的测试数据&#xff0c;计算每队的平均得分 比较各队的平均分&#xff0c;以确定比赛的获胜者&#xff0c;并将其打印到控制台。不要忘了可能会出现平局&#xff0c;所…