nodejs设置强制缓存,协商缓存

协商缓存(Conditional Requests)

协商缓存指的是浏览器每次请求时携带上次请求标识(如 Last-ModifiedETag),服务器通过这些标识判断资源是否修改,如果没有修改,则返回 304 Not Modified 响应。

  • Last-ModifiedIf-Modified-Since:基于资源的最后修改时间进行缓存协商。
  • ETagIf-None-Match:基于资源的内容哈希进行缓存协商。

适用场景:

  • 动态内容:如用户的个人信息页面,这些页面数据可能会经常更新,可以使用协商缓存来减少不必要的传输。
  • API 响应:特别是数据可能频繁变化的 API,可以使用协商缓存减少带宽消耗。

使用 Last-ModifiedIf-Modified-Since 

const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
  const filePath = path.join(__dirname, 'static', 'file.txt'); // 示例文件路径

  fs.stat(filePath, (err, stats) => {
    if (err) {
      res.statusCode = 404;
      res.end('File not found');
      return;
    }

    const lastModified = stats.mtime.toUTCString();

    // 检查 If-Modified-Since 头
    if (req.headers['if-modified-since'] === lastModified) {
      res.statusCode = 304; // Not Modified
      res.end();
      return;
    }

    res.setHeader('Last-Modified', lastModified);
    res.setHeader('Content-Type', 'text/plain');

    const fileStream = fs.createReadStream(filePath);
    fileStream.pipe(res);
  });
});

server.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

 使用 ETagIf-None-Match

const http = require('http');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');

const server = http.createServer((req, res) => {
  const filePath = path.join(__dirname, 'static', 'file.txt'); // 示例文件路径

  fs.readFile(filePath, (err, data) => {
    if (err) {
      res.statusCode = 404;
      res.end('File not found');
      return;
    }

    const hash = crypto.createHash('md5').update(data).digest('hex');
    const etag = `"${hash}"`;

    // 检查 If-None-Match 头
    if (req.headers['if-none-match'] === etag) {
      res.statusCode = 304; // Not Modified
      res.end();
      return;
    }

    res.setHeader('ETag', etag);
    res.setHeader('Content-Type', 'text/plain');

    res.end(data);
  });
});

server.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

总结

  • Last-ModifiedIf-Modified-Since:基于资源的最后修改时间进行缓存协商。
  • ETagIf-None-Match:基于资源的内容哈希进行缓存协商。

强制缓存(Cache-Control)

强制缓存指的是服务器在响应头中设置缓存控制策略,告知浏览器在一定时间内不需要向服务器请求,直接使用本地缓存。常见的 Cache-Control 头值包括:

  • max-age=<seconds>:指定缓存的有效时间,单位是秒。
  • public:表示响应可以被任何缓存存储。
  • private:表示响应只能被用户的浏览器缓存,不能被共享缓存(如代理服务器)存储。
  • no-store:表示不缓存响应。
  • no-cache:表示缓存响应,但是每次使用缓存前必须向服务器验证。

适用场景:

  • 静态资源(如CSS、JS、图片):通常这些资源不会频繁变化,可以设置较长的 max-age
  • API 响应:根据业务需求设置,某些数据(如产品列表)可能每小时更新一次,可以设置适当的 max-age
  • 用户特定数据:如用户的购物车数据,适合 private
const http = require('http');
const fs = require('fs');
const path = require('path');

http.createServer((req, res) => {
    const filePath = path.join(__dirname, 'public', req.url);
    
    fs.readFile(filePath, (err, data) => {
        if (err) {
            res.writeHead(404, { 'Content-Type': 'text/plain' });
            res.end('Not Found');
            return;
        }

        // 设置强制缓存,例如设置缓存一周
        const oneWeekInSeconds = 7 * 24 * 60 * 60;
        res.writeHead(200, {
            'Content-Type': 'text/html',
            // 在浏览器保存指定秒数后过期,优先于Expires
            'Cache-Control': `public, max-age=${oneWeekInSeconds}`,
            // 兼容旧版浏览器,超过指定日期后过期
            'Expires': new Date(Date.now() + oneWeekInSeconds * 1000).toUTCString(),
        });
        
        res.end(data);
    });
}).listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

在express中设置静态资源缓存 

const express = require('express');
const app = express();

app.use('/static', express.static('public', {
  maxAge: '1d', // 强制缓存,缓存一天
  etag: true,   // 协商缓存
  lastModified: true // 协商缓存
}));

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

在koa中设置静态资源缓存

const Koa = require('koa');
const static = require('koa-static');
const path = require('path');

const app = new Koa();

// 配置静态文件服务
app.use(static(path.join(__dirname, 'public'), {
  maxage: 86400000, // 设置静态文件的强制缓存时间,这里是一天,单位是毫秒
  index: false // 关闭默认的索引页
}));

// 监听端口
app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值