记录--关于浏览器缓存策略这件事儿

这篇具有很好参考价值的文章主要介绍了记录--关于浏览器缓存策略这件事儿。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--关于浏览器缓存策略这件事儿

前言

我们打开百度这个网站并刷新多次时时,注意到百度的logo是没有每次都加载一遍的。我们知道图片是img标签中的src属性加载出来的,这也需要浏览器去请求图片资源的,那么为什么刷新多次浏览器只请求了一次图片资源呢?这就涉及到了浏览器的缓存策略了,这张图片被浏览器缓存下来了!

正文

一、为什么要有浏览器的缓存策略?

  • 提升用户体验,减少页面重复的http请求

二、为什么通过浏览器url地址栏访问的html页面不缓存?

  • 强制刷新页面浏览器url地址栏访问资源 时,浏览器默认会在请求头中设置Cache-control: no-cache,如设置该属性浏览器就会忽略响应头中的 Cache-control

如何优化网络资源请求的时间呢?有以下三种方式。

三、CDN网络分发

CDN:CDN会通过负载均衡技术,将用户的请求定向到最合适缓存服务器上去获取内容。

比如说,北京的用户,我们让他访问北京的节点,深圳的用户,我们让他访问深圳的节点。通过就近访问,加速用户对网站的访问,进而解决Internet网络拥堵状况,提高用户访问网络的响应速度。

四、强缓存

强缓存是浏览器的缓存策略,后端设置响应头中的属性值就能设置文件资源在浏览器的缓存时间过了缓存的有效期再次访问时,文件资源需再次加载

强缓存有两种方式来控制资源被浏览器缓存的时长:

  1. 后端设置响应头中的 Cache-control: max-age=3600 来控制缓存时长(为一个小时)
  2. 后端设置响应头中的 Expires:xxx 来控制缓存的截止日期(截止日期为xxx)

我们直接上代码让你更好理解,我们需要实现一个页面,页面上需展现一个标题一张图片

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Earth</h1>
  <img src="assets/image/earth.jpeg" alt="">
</body>
</html>

 

const http = require('http');
const path = require('path');
const fs = require('fs');
const mime = require('mime'); //接收一个文件后缀,返回一个文件类型

const server = http.createServer((req, res) => {
  const filePath = path.resolve(__dirname, `www/${req.url}`)  //resolve合并地址
  if (fs.existsSync(filePath)) {  //判断路径是否有效
    const stats = fs.statSync(filePath)   //获取文件信息
    const isDir = stats.isDirectory()    //是否是文件夹
    if (isDir) {
      filePath = path.join(filePath, 'index.html')
    }
    //读取文件
    if (!isDir || fs.existsSync(filePath)) {

      //判断前端请求的路径的后缀名是图片还是文本
      const { ext } = path.parse(filePath)  //.html .jpeg

      const time = new Date(Date.now() + 3600000).toUTCString()   //定义时间 作为缓存时间的有效期

      let status = 200

      res.writeHead(status, {
        'Content-Type': `${mime.getType(ext)};charset=utf-8`,
        'Cache-control': 'max-age=3600',  //缓存时长为一小时 
        // 'expires': time  //截止日期 缓存一小时后过期
      })

      if (status === 200) {
        const fileStream = fs.createReadStream(filePath)   //将文件读成流类型
        fileStream.pipe(res) //将文件流导入响应体
      }else{
        res.end();
      }

    }
  }
})

server.listen(3000, () => {
  console.log('listening on port 3000');
})

第一次运行:

记录--关于浏览器缓存策略这件事儿

 刷新页面后,可以看到图片资源没有重新加载:

记录--关于浏览器缓存策略这件事儿

三、协商缓存

我们想象这样的场景:当我们偷偷把图片偷偷换成另一张图片,图片名依然和之前那张一样,会是什么结果呢?
操作后,刷新页面发现图片还是之前那张图片,并没有换成新的!那这就出事儿了,后端图片换了,用户看到的还是老图片,有一种方案是改变图片资源的名字,直接请求最新图片资源,但这并不是最优方案,终极方案是需要协商缓存的帮忙。

协商缓存也是浏览器的缓存策略,它也有两种方式辅助强缓存,来判断文件资源是否被修改

1. 后端设置响应头中的 last-modified: xxxx

  • 辅助强缓存,让URL地址栏请求的资源也能被缓存
  • 辅助强缓存,借助请求头中的if-modified-since来判断资源文件是否被修改,如果被修改则返回新的资源,否则返回304状态码,让前端读取本地缓存

代码如下:

const http = require('http');
const path = require('path');
const fs = require('fs');
const mime = require('mime'); //接收一个文件后缀,返回一个文件类型

const server = http.createServer((req, res) => {
  const filePath = path.resolve(__dirname, `www/${req.url}`)  //resolve合并地址
  if (fs.existsSync(filePath)) {  //判断路径是否有效
    const stats = fs.statSync(filePath)   //获取文件信息
    const isDir = stats.isDirectory()    //是否是文件夹
    if (isDir) {
      filePath = path.join(filePath, 'index.html')
    }
    //读取文件
    if (!isDir || fs.existsSync(filePath)) {

      //判断前端请求的路径的后缀名是图片还是文本
      const { ext } = path.parse(filePath)  //.html .jpeg

      const time = new Date(Date.now() + 3600000).toUTCString()   //定义时间 作为缓存时间的有效期

      const timeStamp = req.headers['if-modified-since']  //请求头的if-modified-since字段
      let status = 200

      //判断文件是否修改过
      if (timeStamp && Number(timeStamp) === stats.mtimeMs) {  //timeStamp为字符串 转换为number类型判断
        status = 304
      }

      res.writeHead(status, {
        'Content-Type': `${mime.getType(ext)};charset=utf-8`,
        'Cache-control': 'max-age=3600',  //缓存时长为一小时   //max-age=0或no-cache不需要缓存
        // 'expires': time  //截止日期 缓存一小时后过期
        'last-modified': stats.mtimeMs //文件最后一次修改时间
      })

      if (status === 200) {
        const fileStream = fs.createReadStream(filePath)   //将文件读成流类型
        fileStream.pipe(res) //将文件流导入响应体
      }else{
        res.end();
      }

    }
  }
})

server.listen(3000, () => {
  console.log('listening on port 3000');
})
我们只要对比last-modified的值和if-modified-since的值有无变化即可:

记录--关于浏览器缓存策略这件事儿

2. Etag:文件的标签

  • 请求头中会被携带If-None-Match
  • Etag保证了每一个资源是唯一的,资源变化都会导致Etag变化。服务器根据If-None-Match值来判断是否命中缓存。 当服务器返回304的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。

记录--关于浏览器缓存策略这件事儿

 代码如下:

const http = require('http');
const path = require('path');
const fs = require('fs');
const mime = require('mime'); //接收一个文件后缀,返回一个文件类型
const md5 = require('crypto-js/md5');

const server = http.createServer((req, res) => {
  const filePath = path.resolve(__dirname, `www/${req.url}`)  //resolve合并地址
  if (fs.existsSync(filePath)) {  //判断路径是否有效
    const stats = fs.statSync(filePath)   //获取文件信息
    const isDir = stats.isDirectory()    //是否是文件夹
    if (isDir) {
      filePath = path.join(filePath, 'index.html')
    }
    //读取文件
    if (!isDir || fs.existsSync(filePath)) {

      //判断前端请求的路径的后缀名是图片还是文本
      const { ext } = path.parse(filePath)  //.html .jpeg
      const content = fs.readFileSync(filePath);
      let status = 200

      //判断文件是否被修改过
      if (req.headers['if-none-match'] == md5(content)) {
        status=304
      }

      res.writeHead(status, {
        'Content-Type': `${mime.getType(ext)};charset=utf-8`,
        'Cache-control': 'max-age=3600',  //缓存时长为一小时   //max-age=0或no-cache不需要缓存
        'Etag': md5(content)  //文件资源的md5值
      })

      if (status === 200) {
        const fileStream = fs.createReadStream(filePath)   //将文件读成流类型
        fileStream.pipe(res) //将文件流导入响应体
      } else {
        res.end();
      }

    }
  }
})

server.listen(3000, () => {
  console.log('listening on port 3000');
})

最后附上一张图便于更好理解浏览器的缓存策略:

记录--关于浏览器缓存策略这件事儿

 

本文转载于:

https://juejin.cn/post/7253675120010199101

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--关于浏览器缓存策略这件事儿文章来源地址https://www.toymoban.com/news/detail-541645.html

到了这里,关于记录--关于浏览器缓存策略这件事儿的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 浏览器安全之同源策略

    原文合集地址如下,有需要的朋友可以关注 本文地址 合集地址 浏览器的同源策略是一种安全机制,用于保护用户信息和防止恶意代码的执行。它是由浏览器实施的一组规则,限制了不同源(origin)的网页之间的交互。 同源是指两个网页具有相同的协议(protocol),主机(

    2024年02月11日
    浏览(42)
  • 浏览器缓存原理

    使用 HTTP 缓存的好处 :通过复用缓存资源,减少了客户端等待服务器响应的时间和网络流量,同时也能缓解服务器端的压力。可以显著的提升网站的应用性能。 HTTP 缓存策略分为两种 :强制缓存、协商缓存。 强制缓存 浏览器缓存没有过期的时候可以直接决定使用缓存。 强

    2023年04月27日
    浏览(33)
  • 浏览器缓存机制

    什么是浏览器缓存 浏览器缓存就是浏览器根据 url 第一次访问网站之后,将网站的 html、css、js、图片等文件复制一份保留到浏览器中,当你二次访问这个 url 的网站时,如果网站没有明确表示有更新时,浏览器直接在缓存中查找内容,不会再次请求网页内容,只有网页明确表

    2024年02月04日
    浏览(45)
  • 前端---需要了解浏览器相关知识--浏览器请求服务器资源---缓存

    掘金1:浏览器缓存 掘金2 :浏览器缓存 跟别人怎么讲,从大的说:缓存的原理是什么? 再说什么是浏览器缓存? 浏览器缓存 请求(静态资源 | 动态资源) 一、缓存是什么? 二、为什么? 浏览器是如何判断是否使用缓存的??第一次请求网页 第二次请求相同网页: 三、怎

    2024年02月12日
    浏览(46)
  • 强缓存、协商缓存(浏览器的缓存机制)是么子?

    为了减少资源请求次数,加快资源访问速度,浏览器会对资源文件如图片、css文件、js文件等进行缓存 所谓强缓存,可以理解为强制缓存的意思,即浏览器在访问某个资源时会判断是否使用本地缓存里已经存在的资源文件,使用本地缓存的话则不会发送请求到服务器,从而达

    2024年01月20日
    浏览(39)
  • nginx配置浏览器缓存(强缓存、协商缓存、无缓存)

    下载地址:点击下载nginx 根据系统选择要下载的安装包,这里最好选择稳定版(stable version)。 下载好后解压该zip,将解压后的文件夹放在自己喜欢的目录下,我是放在J盘(自己分的磁盘)下。 进入J:nginx-1.22.0目录,目录结构: 注:project目录是我自己创建的,用于存放打包

    2024年02月09日
    浏览(30)
  • 浏览器安全-同源策略和CORS

    同源策略是浏览器的一个安全功能,浏览器禁止在当前域读写其他域的资源,如限制跨域发送ajax请求 不受同源策略限制的 1)页面中的链接,重定向表单以及表单提交 2)跨域资源引入 如script不受跨域限制,可以跨域请求src 如何解决跨域访问资源 1)利用script的跨域特性绕过

    2024年02月09日
    浏览(41)
  • 浏览器的同源策略 - 跨域问题

    跨域问题的实质是浏览器的同源策略造成的。浏览器同源策略是浏览器为 JavaScript 施加的限制。简单点说就是非同源会出现如下等限制: 无法访问其他源下的网页的 Cookies,Storage等; 无法访问其他源下的DOM对象和 JS 对象; 无法使用 Ajax 向其他源发送请求(除非其他源允许)

    2024年02月15日
    浏览(33)
  • 真的只是简单了解下浏览器缓存

    当我们打开一个页面时,会向服务端发起很多次请求,如下图打开百毒首页,发起了HTML、各种图片、JS、CSS等资源共72次请求。这里面很多资源并不会频繁变化,每次打开页面都重新请求下载,就很浪费了。 浏览器缓存也称为HTTP缓存,HTTP缓存 简单理解就是本地(浏览器)缓

    2023年04月25日
    浏览(33)
  • 浏览器缓存引发的odoo前端报错

    前两天,跑了一个odoo16项目,莫名其妙的前端报错, moment.js 报的错, 这是一个时间库,不是我自己写的代码,我也没做过任何修改,搞不清楚为什么报错。以为是odoo的bug,所以从gitee下载了odoo16最新的代码,测试了一下还是报错。 后来换成了一个非常老的odoo16版本,这回不

    2024年02月02日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包