强缓存和协商缓存前端和后端如何实现

515 阅读2分钟

前端和后端的缓存实现方式也有所不同。下面以JavaScript和Node.js技术为例,简单介绍前端和后端如何实现强缓存和协商缓存。

前端缓存实现

前端缓存主要是通过设置HTTP响应头来实现的。在浏览器发送HTTP请求时,可以在HTTP响应头中添加Expires、Cache-Control等字段,告诉浏览器该资源的缓存时间和过期时间。例如,以下代码片段可以设置一个静态资源(如图片)的缓存时间:

// 设置静态资源的缓存时间为1小时
res.setHeader('Expires', new Date(Date.now() + 3600000).toUTCString());
res.setHeader('Cache-Control', 'max-age=' + 3600);

这样,当该静态资源再次被请求时,浏览器会首先检查本地缓存是否过期,如果没有过期,则直接从本地缓存读取资源,并返回一个200响应;如果过期了,则向服务器请求新的资源,并将其缓存在本地。这就是强缓存的实现方式。

后端缓存实现

在 Node.js 中,可以使用内置的 HTTP 模块来实现 Last-Modified 和 ETag 的实现。以下是一个简单的示例代码:

const http = require('http');
const fs = require('fs');
const path = require('path');
const { parse } = require('url');

const server = http.createServer((req, res) => {
  const url = parse(req.url);
  const filePath = path.join(__dirname, url.pathname);

  // 获取文件状态信息
  fs.stat(filePath, (err, stats) => {
    if (err) {
      res.statusCode = 404;
      res.end('Not found');
      return;
    }

    // 获取文件最后修改时间
    const lastModified = stats.mtime.toUTCString();

    // 获取文件唯一标识符
    const fileETag = `${stats.size}-${stats.mtime.getTime()}`;

    // 设置响应头信息
    res.setHeader('Last-Modified', lastModified);
    res.setHeader('ETag', fileETag);

    // 判断客户端是否有缓存
    const ifModifiedSince = req.headers['if-modified-since'];
    const ifNoneMatch = req.headers['if-none-match'];

    if (ifModifiedSince === lastModified || ifNoneMatch === fileETag) {
      res.statusCode = 304;
      res.end();
      return;
    }

    // 读取文件内容并返回
    const stream = fs.createReadStream(filePath);
    stream.pipe(res);
  });
});

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

上述代码中,我们首先使用 fs.stat() 方法获取请求的文件的状态信息,然后分别计算出了文件的最后修改时间和唯一标识符,并将它们设置到了响应头中。接着,我们判断客户端是否缓存了该文件,并根据需要返回相应的响应码。最后,我们使用 fs.createReadStream() 方法读取文件内容,并通过管道流将其返回给客户端。

需要注意的是,在实际开发中,我们可能需要考虑更多的细节,例如缓存过期时间、缓存策略等。此外,以上只是示例代码,生产环境下还需要对代码进行优化和安全性检查。