上一篇文章《详解页面静态资源的缓存策略,搞懂强缓存和协商缓存再做性能优化》我们从理论上介绍了浏览器和服务器是如何对静态资源做缓存的,这篇文章我们把它做成一个node服务器的静态资源中间件。

代码开发

既然是开发中间件,肯定是服务端要做的事情,大致流程如下:

图1

  • 服务器接收到请求,先解析地址path(一般都是通过path对应到工程下的具体文件);
  • 检查缓存头标志,如果内容没过期,仅修改头信息,304状态返回,如果内容过期了,就要正常返回内容。

图2

我们在static.js文件中开发,这个中间件允许设置目录和其他参数,如图2所示。

图3

如果不是GET或者HEAD请求,可以直接跳过这个中间件,也可以直接返回点什么!

图4

如何获取服务器静态文件的路径?如果设置了根目录,就把请求地址的pathname拼在根目录后面,如果没有设置根目录,就把pathname直接当做文件路径。

图5

当我们拿到文件路径后,需要判断这个路径是否真实存在?如果存在,它就有可能是文件夹,也有可能是文件,我们先处理是文件的情况。

图6

此处我们直接使用mime这个包来设置content-type。

除了图5中处理文件夹的逻辑,还有当请求的路径最后一个字符是“/”时,也需要被当做文件夹处理。如果是文件夹,就需要设置文件夹下的默认文件,一般是index.html。

图7

如图7所示,有两处需要处理文件夹,我们抽取一下逻辑。

图8

options.index可以配置文件夹下默认的文件,类型是数组。如果找到一个存在的文件,就返回这个文件。那么图6中处理单个文件的逻辑和此处一致,可以抽取出来——hanleFile。

代码写到这里,我们的服务已经可以正常返回静态文件的内容了,但是我们还没有设置缓存响应头,下面我们继续开发。

图9

如图9所示,我们设置了Cache-Control、Last-Modify和Etag响应头(etag的获取我们直接利用etag模块计算)。

当一个请求非第一次到达服务器,它有可能带着缓存信息,所以我们要判断文件缓存是否过期,如果没有过期,就返回304状态。

图10

如图10,我们对比一下【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对请求响应头,这是文件内容是否变化的主要依据。

图11

如图11,只要符合服务器的缓存策略(etag==if-none-match或者last-modified<=If-modified-since),就可以返回304状态。

实例

图12

如图12所示,我们写个demo测试一下,效果如下:

图13

从上面的效果看,我们可以发现,第一次请求是200,第二次请求会变成304,说明缓存策略生效了,符合预期!

总结

这篇文章主要是把之前的理论变成能实际应用的代码,虽然还有很多地方需要打磨,但是主体逻辑已经成型,从中可以学习一下思路。

喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!

glide默认的缓存图片路径地址_手写一个静态资源中间件,加深了解服务器对文件请求的缓存策略...相关推荐

  1. html如何获取请求头变量的值。_手写一个静态资源中间件,加深了解服务器对文件请求的缓存策略...

    上一篇文章<详解页面静态资源的缓存策略,搞懂强缓存和协商缓存再做性能优化>我们从理论上介绍了浏览器和服务器是如何对静态资源做缓存的,这篇文章我们把它做成一个node服务器的静态资源中间件. ...

  2. 服务器策略文件,如何解决服务器对文件请求的缓存策略教程

    我们从理论上介绍了浏览器和服务器是如何对静态资源做缓存的,这篇文章我们把它做成一个node服务器的静态资源中间件. 代码开发 既然是开发中间件,肯定是服务端要做的事情,大致流程如下: 图1 服务器接收 ...

  3. 未能加载文件或程序集或它的某一个依赖项_手写一个miniwebpack

    前言 之前好友希望能介绍一下 webapck 相关的内容,所以最近花费了两个多月的准备,终于完成了 webapck 系列,它包括一下几部分: webapck 系列一:手写一个 JavaScript 打 ...

  4. 手写一个promise用法_手写一个 Promise

    1 js 的基本数据类型? 2 JavaScript 有几种类型的值? 3 什么是堆?什么是栈?它们之间有什么区别和联系? 4 内部属性 [Class] 是什么? 5 介绍 js 有哪些内置对象? 6 ...

  5. javascript实现图片轮播_手撸一个简易版轮播图(上)

    手撸一个简易版轮播图 实现原理,通过控制 swiper-warpper 容器的定位来达到切换图片的效果. 页面布局 简易版轮播图 < > 页面样式 .container{width: 60 ...

  6. django 不包括字段 序列化器_手写一个Django序列化功能

    本文章的代码已上传至github上(github包含了更多功能,相关文章后续更新) AGL1994/django-building​github.com 前言 目前Django比较知名的序列化框架有D ...

  7. glide默认的缓存图片路径地址_Glide图片硬盘缓存使用详解

    Glide缓存工具类 */ @SuppressWarnings("ResultOfMethodCallIgnored") public class GlideCacheUtil { ...

  8. 手写一个promise用法_手写一个自己的 JavaScript Promise 类库

    终于有时间写这篇文章了, ES2015 推出了JS 的 Promise ,而在没有原生支持的时候,我们也可以使用诸如 Promises/A+ 的库的帮助,在我们的代码里实现Promise 的支持: 如 ...

  9. 手写一个promise用法_手写一个Promise

    JS面向对象 在JS中一切皆对象,但JS并不是一种真正的面向对象(OOP)的语言,因为它缺少类(class)的概念.虽然ES6引入了class和extends,使我们能够轻易地实现类和继承.但JS并不 ...

最新文章

  1. 我们人类与人工智能技术究竟是怎样的关系?
  2. VR/AR行业发展至今,它的市场规模如何
  3. elasticsearch best_fields most_fields cross_fields从内在实现看区别——本质就是前两者是以field为中心,后者是词条为中心...
  4. 不懂编程可以自学python吗-python教程看完了,还是不会编程?
  5. 排序算法java 简书_史上最全经典排序算法总结(Java实现)
  6. 博士申请 | ​麦吉尔大学智能自动化实验招收2022年秋季入学全奖博士生
  7. 嵌入式常见笔试题总结(4)
  8. 一款零注解API接口文档生成工具
  9. linux路由内核实现分析(四)---路由缓存机制(2)
  10. ASCII码从小到大排序(字典序)
  11. GDAL使用DEM数据计算山体阴影(Hillshade)
  12. 常用指令备忘录----持续更新
  13. 【lidar】单目深度估计与伪雷达点云、可视化
  14. 汽车距离报警系统c语言编程,基于单片机的汽车防盗报警系统设计与实现.doc
  15. 关于xlrd不支持xlsx格式的解决办法
  16. 组装高性能服务器电脑,工作站专用 7.3万元高性能服务器电脑配置推荐
  17. 修改脚本、WSH 让系统不被恶意代码篡改
  18. Daily English(每日一句)
  19. 当Forms表单遇到Power BI
  20. 【Week15作业 B】ZJM与生日礼物【字典树】

热门文章

  1. linux常用命令(1)帮助命令man使用
  2. keepalived实现nginx高可用主备集群配置过程
  3. Ubuntu21.04 deepin-wine 微信输入中文乱码,黑块,和多余窗口问题解决
  4. CAS无锁(乐观锁、自旋锁)优化
  5. Scala模式匹配:for循环表达式中的模式匹配
  6. Python Django 日期增减API
  7. eureka之EurekaClientConfig的作用
  8. Mybatis DAO开发--Mapper动态代理开发方式
  9. JTextPane设置颜色出现的问题
  10. matlabpython建模_一直在用Matlab建模,现在Python很火,用学么?