node实现缓存
内容:
1.缓存基本原理
2.node实现缓存
1.缓存基本原理
第一重要、缓存策略:
- cache-control:用于控制缓存,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private
- expires:失效时间
第二重要、缓存实现过程:
- 第一次Server->Client:"Last-Modified: Sat, 02 Dec 2017 04:03:14 GMT" --> 服务端告诉客户端资源修改的时间
- 第二次Client->Server:"If-Modified-Since: Sat, 02 Dec 2017 04:03:14 GMT" --> 浏览器告诉服务器自己缓存的资源的修改时间
- 第二次Server->Client:200 || 304 --> 服务器根据两者时间是否相同决定返回200(返回新资源)还是304(叫浏览器用自己缓存的资源)
注意:
- cookie不属于缓存!
- 关于localstorage:https://www.cnblogs.com/st-leslie/p/5617130.html
2.node实现缓存
源码:
const http=require('http');
const fs=require('fs');
const url=require('url'); // 连续两次访问: http://localhost:8080/1.html 第一次是200 第二次是304
http.createServer((req, res)=>{
let {pathname}=url.parse(req.url); //获取文件日期
fs.stat(`www${pathname}`, (err, stat)=>{
if(err){
res.writeHeader(404);
res.write('Not Found');
res.end();
}else{
// 请求头中有if-modified-since -> 不是第一次请求,之前浏览器中缓存了该页面
if(req.headers['if-modified-since']){
let oDate=new Date(req.headers['if-modified-since']);
let time_client=Math.floor(oDate.getTime()/1000);
let time_server=Math.floor(stat.mtime.getTime()/1000); if(time_server>time_client){ // 服务器的文件时间 > 客户端手里的版本
sendFileToClient();
}else{
res.writeHeader(304);
res.write('Not Modified');
res.end();
}
}
// 请求头中没有if-modified-since -> 第一次请求 -> 直接返回要的文件
else{
sendFileToClient();
} // 直接返回文件
function sendFileToClient(){
//发送
let rs=fs.createReadStream(`www${pathname}`); res.setHeader('Last-Modified', stat.mtime.toGMTString()); //输出
rs.pipe(res); rs.on('error', function(err){
res.writeHeader(404);
res.write('Not Found');
res.end();
});
}
}
});
}).listen(8080);
原理:
- 服务端第一次向客户端发送资源时设置文件修改时间:setHeader('Last-Modified', stat.mtime.toGMTString())
- 之后客户端向浏览器请求时服务端检查请求头中是否有if-modified-since:
- 如果有if-modified-since就判断服务器时间是否大于浏览器时间(若大于说明服务端文件已经修改就将新修改的文件返回,否则就返回304浏览器会直接使用原先缓存的资源)
- 如果没有if-modified-since就直接返回文件并像最上面那样设置文件修改时间
另外还可以设置缓存:
// 具有缓存控制的服务器 --> 设置Cache-Control(no-cache)
const http=require('http');
const fs=require('fs');
const url=require('url'); // 连续两次访问: http://localhost:8080/1.html 第一次是200 第二次是304
http.createServer((req, res)=>{
let {pathname}=url.parse(req.url); //获取文件日期
fs.stat(`www${pathname}`, (err, stat)=>{
if(err){
res.writeHeader(404);
res.write('Not Found');
res.end();
}else{
// 请求头中有if-modified-since -> 不是第一次请求,之前浏览器中缓存了该页面
if(req.headers['if-modified-since']){
let oDate=new Date(req.headers['if-modified-since']);
let time_client=Math.floor(oDate.getTime()/1000);
let time_server=Math.floor(stat.mtime.getTime()/1000); if(time_server>time_client){ // 服务器的文件时间 > 客户端手里的版本
sendFileToClient();
}else{
res.writeHeader(304);
res.write('Not Modified');
res.end();
}
}
// 请求头中没有if-modified-since -> 第一次请求 -> 直接返回要的文件
else{
sendFileToClient();
} // 直接返回文件
function sendFileToClient(){
//发送
let rs=fs.createReadStream(`www${pathname}`); // 设置缓存
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Last-Modified', stat.mtime.toGMTString()); //输出
rs.pipe(res); rs.on('error', function(err){
res.writeHeader(404);
res.write('Not Found');
res.end();
});
}
}
});
}).listen(8080);
node实现缓存的更多相关文章
- node.js缓存处理方式
Node.JS缓存处理分为客户端和服务端两个部分. 客户端的缓存主要是利用浏览器对HTTP协议响应头中cache-control和expires字段的支持.浏览器在得到明确的响应头后,会将文件缓存在本 ...
- Node.js缓存
Node.js Buffer(缓冲区) JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 ...
- 深入浅出node(2) 模块机制
这部分主要总结深入浅出Node.js的第二章 一)CommonJs 1.1CommonJs模块定义 二)Node的模块实现 2.1模块分类 2.2 路径分析和文件定位 2.2.1 路径分析 2.2.2 ...
- 缓存淘汰算法--LRU算法
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也 ...
- JavaScript实现TwoQueues缓存模型
本文所指TwoQueues缓存模型,是说数据在内存中的缓存模型. 无论何种语言,都可能需要把一部分数据放在内存中,避免重复运算.读取.最常见的场景就是JQuery选择器,有些Dom元素的选取是非常耗时 ...
- node学习笔记
一.准备(github地址) 什么是Javascript? ... Javascript能做什么? ..... 浏览器中的Javascript可以做什么? 操作DOM(增删改查) AJAX/跨域 BO ...
- JPA,EclipseLink 缓存机制学习(一) 树节点搜索问题引发的思考
最近在项目在使用JPA+EclipseLink 的方式进行开发,其中EclipseLink使用版本为2.5.1.遇到一些缓存方面使用不当造成的问题,从本篇开始逐步学习EclipseLink的缓存机制. ...
- 浅析LRU(K-V)缓存
LRU(Least Recently Used)算法是缓存技术中的一种常见思想,顾名思义,最近最少使用,也就是说有两个维度来衡量,一个是时间(最近),一个频率(最少).如果需要按优先级来对缓存中的K- ...
- Node.js的模块载入方式与机制
Node.js中模块可以通过文件路径或名字获取模块的引用.模块的引用会映射到一个js文件路径,除非它是一个Node内置模块.Node的内置模块公开了一些常用的API给开发者,并且它们在Node进程开始 ...
随机推荐
- Qt QML referenceexamples attached Demo hacking
/********************************************************************************************* * Qt ...
- Linux基础和网络管理上机试题 - imsoft.cnblogs
一.(使用at命令实现任务的的自动化,要求用一条条的指令完成) 找出系统中任何以txt为后缀名的文档,并且进行打印.打印结束后给用户foxy发出邮件通知取件.指定时间为十二月二十五日凌晨两点 ...
- Visual Studio Code 使用指南
安装 VSCode是微软推出的一款轻量编辑器,采取了和VS相同的UI界面,搭配合适的插件可以优化前端开发的体验. HTML Snippets:增强了zen-coding,增加了H5的自动补全,安 ...
- java反射+java泛型,封装BaseDaoUtil类。供应多个不同Dao使用
当项目是ssh框架时,每一个Action会对应一个Service和一个Dao.但是所有的Ation对应的Dao中的方法是相同的,只是要查的表不一样.由于封装的思想,为了提高代码的重用性.可以使用jav ...
- hadoop yarn 知识点
yarn 简介: Yarn是一个分布式的资源管理系统,用以提高分布式的集群环境下的资源利用率,这些资源包括内存.IO.网络.磁盘等.其产生的原因是为了解决原MapReduce框架的不足.最初MapRe ...
- 线性模型的fit,predict
线性模型的fit其实一个进行学习的过程,根据数据和标签进行学习:predict则是基于fit之后形成的模型,来决定指定的数据对应于标签(y_train_5)的值. 下面的是手写字母判断是否为“5” s ...
- QString 和char数组转换(转)
在qt开发过程中经常遇到QString类和char数组进行转换,在此记录一下: QString->char数组 1 2 3 QString str="12fff"; QByt ...
- 【jmeter】Jmeter进行分布式性能测试
由于Jmeter本身的瓶颈,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至还会引起JAVA内存溢出的错误.要解决这个问题,可以使用分布式测试,运行多台机器运行所谓的 ...
- 新玩具,React v16.7.0-alpha Hooks
周五看见React v16.7.0-alpha Hooks,今早起来看见圈里已经刷屏了Hooks,正好周末,正好IG和G2的比赛还没开始,研究下... 刚刚接触react时候非常喜欢用函数式组件,因为 ...
- Qt Creator 预览QtCreator中的界面
当在QtCreator界面编辑器中放置好布局和控件之后,组合键 Alt + Shift + R 可以实现预览功能. 也可以通过以下方式更改快捷键: 具体路径 ...