Node.js如何实现浏览器缓存
沉沙 2018-05-15 来源 : 阅读 723 评论 0

摘要:本文详细讲解了Node.js实现浏览器缓存的方法,希望学习本文后对大家有所帮助,学会如何实现浏览器缓存。

Node.js如何实现浏览器缓存

使用缓存的流程示意图

下面从三个规则分别来讲:

1. 添加Expires或Cache-Control到报文头中;

2. 配置Etags;

3. 让Ajax缓存。

· 条件请求

请求头部设置了If-Modified-Since,浏览器向服务器请求资源,服务端返回304状态码,浏览器则会使用本地文件。

 

var handle = function (req, res) {
    fs.stat(filename, function (err, stat) {
        var lastModified = stat.mtime.toUTCString();
        if (lastModified === req.headers['if-modified-since']) {
            res.writeHead(304, "Not Modified");
            res.end();
        } else {
            fs.readFile(filename, function(err, file) {
                var lastModified = stat.mtime.toUTCString();
                res.setHeader("Last-Modified", lastModified);
                res.writeHead(200, "Ok");
                res.end(file);
            });
        }
    });
};

 

这里采用时间戳的方式来实现,时间戳的方式有一些缺陷:

文件的时间戳改动了但内容不一定改动。

时间戳只能精确到秒级别,更新频繁的内容将无法生效。

Etags(Entity Tag)可以解决这个问题,由服务端生成,生成规则随意。一般是根据文件内容生成散列值,那么条件请求将不会受到时间戳改动造成带宽的浪费。与If-Modified-Since/Last-Modified不同的是,Etags的请求相应是:If-None-Match/ETag

 

var getHash = function (str) {
    var shasum = crypto.createHash('sha1');
    return shasum.update(str).digest('base64');
};
var handle = function (req, res) {
    fs.readFile(filename, function(err, file) {
        var hash = getHash(file);
        var noneMatch = req.headers['if-none-match'];
        if (hash === noneMatch) {
            res.writeHead(304, "Not Modified");
            res.end();
        } else {
            res.setHeader("ETag", hash);
            res.writeHead(200, "Ok");
            res.end(file);
        }
    });
};

 

尽管条件请求可以在文件内容没有改变的情况下节省带宽,但是还是需要请求服务器,那么可以不请求服务器直接取本地文件吗?

· 非条件请求(在服务端响应内容时,让浏览器明确地将内容缓存起来)

Expires是一个GMT格式的时间字符串(GMT时间与北京时间相互可以转化),在服务器端设置Expires可以告知浏览器要缓存的内容,只要本地还存在这个文件,在过期时间之前,都不会再发起请求。

 

var handle = function (req, res) {
    fs.readFile(filename, function(err, file) {
        var expires = new Date();
        expires.setTime(expires.getTime() + 10 * 365 * 24 * 60 * 60 * 1000);
        res.setHeader("Expires", expires.toUTCString());
        res.writeHead(200, "Ok");
        res.end(file);
    });
};

 

*缺陷:如果用户本地时间和服务器时间不一致,那么这个缓存机制就存在问题。

Cache-Control可以避免这个问题,Cache-Control设置了一个max-age值,表示经过多长时间之后过期。(Cache-Control的优先级高于Expires)

 

var handle = function (req, res) {
    fs.readFile(filename, function(err, file) {
        res.setHeader("Cache-Control", "max-age=" + 10 * 365 * 24 * 60 * 60 * 1000);
        res.writeHead(200, "Ok");
        res.end(file);
    });
};

 

本文由职坐标整理发布,更多相关知识,请关注职坐标WEB前端Node.js频道!


本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程