我们已经从理论上介绍了浏览器和服务器是如何缓存静态资源的。静态资源中间件。代码开发既然是开发中间件,那肯定是服务端要做的事情。大致流程如下:图1服务端收到请求后,首先解析地址路径(一般是通过项目下具体文件对应的路径);检查缓存头部Flag,如果内容没有过期,只修改头部信息,返回304状态。如果内容已经过期,必须正常返回内容。图2我们在static.js文件中开发,这个中间件允许设置目录等参数,如图2所示。如果不是图3中的GET或者HEAD请求,可以直接跳过这个中间件,或者你可以直接退货!图4如何获取服务器静态文件的路径?如果设置了根目录,就把请求地址的pathname放到根目录下,如果没有设置根目录,就直接使用pathname作为文件路径。图5获取到文件路径后,我们需要判断该路径是否真的存在?如果存在,则可能是文件夹或文件。让我们先处理文件的情况。图6这里我们直接使用mime包来设置content-type。除了图5处理文件夹的逻辑外,当请求路径的最后一个字符为“/”时,也需要将其作为文件夹处理。如果是文件夹,需要设置文件夹下的默认文件,一般是index.html。图7如图7所示,有两个文件夹需要处理。让我们提取逻辑。图8options.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来测试一下。效果如下:动画请点这里。从上面的效果我们可以发现第一次请求是200,第二次请求会变成304,说明缓存策略生效了,符合预期!综上所述,本文主要是将前面的理论转化为可以在实践中应用的代码。虽然还有很多需要打磨的地方,但是主要逻辑已经形成,可以借鉴。
