2016/09/12 · JavaScript
· 1 评论 ·
缓存
原版的书文出处: jrainlau
说到前端缓存,超越六分之三人想到的可是是多少个健康的方案,例如cookie
,localStorage
,sessionStorage
,只怕加上indexedDB
和webSQL
,以及manifest
离线缓存。除此而外,到底还有未有其他办法能够张开前端的数额缓存呢?那篇小说将会带您一起来斟酌,怎么着一步一步地由此png图的rgba值来缓存数据的黑科技(science and technology)之旅。
一.小知识点总计
Node.js
是单进度单线程应用程序,但是经过事件和回调支持并发,所以质量尤其高。
nodejs由以下模块组合:
引进 required 模块:大家得以使用 require 指令来载入 Node.js 模块。
创办服务器:服务器能够监听客户端的乞求,类似于 Apache 、Nginx 等 HTTP
服务器。
接收请求与响应请求 服务器很轻易创造,客户端能够利用浏览器或终点发送 HTTP
请求,服务器收到请求后再次回到响应数据。
2016/07/12 · JavaScript
· 4 评论 ·
HTML5
初稿出处: VaJoy
点不清开采的童鞋都以孤独混江湖、夜宿城中村,要是居住的地点安保欠缺,那么出门在外难免挂念屋里的财产安全。
实质上世面上有诸多贤人上的防盗设备,但对于灵动的前端童鞋来讲,只要有一台附带摄像头的Computer,就足以省略地贯彻三个防盗监察和控制系统~
纯 JS 的“防盗”才干极大程度借助于 H五 canvas
的力量,且卓殊风趣。假诺你对 canvas
还面生,能够先点这里翻阅作者的不计其数教程。
step一. 调用录制头
我们须要先在浏览器上访问和调用录制头,用来监督屋子里的举措。分歧浏览器中调用录制头的
API 都略有出入,在此处大家以 chrome 做示范:
JavaScript
<video width=”640″ height=”480″ autoplay></video>
<script> var video = document.querySelector(‘video’);
navigator.webkitGetUserMedia({ video: true }, success, error); function
success(stream) { video.src = window.webkitURL.createObjectURL(stream);
video.play(); } function error(err) { alert(‘video error: ‘ + err) }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<video width="640" height="480" autoplay></video>
<script>
var video = document.querySelector(‘video’);
navigator.webkitGetUserMedia({
video: true
}, success, error);
function success(stream) {
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}
function error(err) {
alert(‘video error: ‘ + err)
}
</script>
|
运维页面后,浏览器出于安全性思量,会领会是或不是允许当前页面访问你的录像头设备,点击“允许”后便能一向在
<video> 上看到拍片头捕获到的镜头了:
step2. 捕获 video 帧画面
只可是开着视频头监视房间可未有别的意义,浏览器不会帮您对监督画面实行剖析。所以那里大家顺遂动用脚本捕获
video 上的帧画面,用于在持续进展数量解析。
从那里发轫大家就要借助 canvas
力量了。在 Canvas入门(五)一文大家介绍过 ctx.drawImage()
方法,通过它能够捕获 video 帧画面并渲染到画布上。
大家必要创制2个画布,然后这么写:
JavaScript
深究前端黑科技(science and technology),创设1个服务器能依靠不一样的url地址请求例外的文本模板。<video width=”640″ height=”480″ autoplay></video> <canvas
width=”640″ height=”480″></canvas> <script> var video =
document.querySelector(‘video’); var canvas =
document.querySelector(‘canvas’); // video捕获摄像头画面
navigator.webkitGetUserMedia({ video: true }, success, error); function
success(stream) { video.src = window.webkitUGL450L.createObjectU哈弗L(stream);
video.play(); } function error(err) { alert(‘video error: ‘ + err) }
//canvas var context = canvas.getContext(‘二d’); setTimeout(function(){
//把当前录制帧内容渲染到画布上 context.drawImage(video, 0, 0, 640, 480);
}, 伍仟); </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<video width="640" height="480" autoplay></video>
<canvas width="640" height="480"></canvas>
<script>
var video = document.querySelector(‘video’);
var canvas = document.querySelector(‘canvas’);
// video捕获摄像头画面
navigator.webkitGetUserMedia({
video: true
}, success, error);
function success(stream) {
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}
function error(err) {
alert(‘video error: ‘ + err)
}
//canvas
var context = canvas.getContext(‘2d’);
setTimeout(function(){
//把当前视频帧内容渲染到画布上
context.drawImage(video, 0, 0, 640, 480);
}, 5000);
</script>
|
如上代码所示,5秒后把摄像帧内容渲染到画布上(下方右图):
step③. 对抓获的三个帧画面推行差异混合
在上面我们关系过,要得力地辨别某些场景,必要对录制镜头进行数据解析。
那么要怎么辨识我们的房舍是或不是有人忽然闯入了吗?答案异常粗略 —— 定期地破获
video 画面,然后比较前后两帧内容是或不是存在比较大变迁。
我们先简单地写3个按时捕获的方法,并将捕获到的帧数据存起来:
JavaScript
//canvas var context = canvas.getContext(‘2d’); var preFrame, //前壹帧
curFrame; //当前帧 //捕获并保存帧内容 function captureAndSaveFrame(){
console.log(context); preFrame = curFrame; context.drawImage(video, 0,
0, 640, 480); curFrame = canvas.toDataUHavalL; //转为base64并保存 }
//按时捕获 function timer(delta){ setTimeout(function(){
captureAndSaveFrame(); timer(delta) }, delta || 500); } timer();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//canvas
var context = canvas.getContext(‘2d’);
var preFrame, //前一帧
curFrame; //当前帧
//捕获并保存帧内容
function captureAndSaveFrame(){ console.log(context);
preFrame = curFrame;
context.drawImage(video, 0, 0, 640, 480);
curFrame = canvas.toDataURL; //转为base64并保存
}
//定时捕获
function timer(delta){
setTimeout(function(){
captureAndSaveFrame();
timer(delta)
}, delta || 500);
}
timer();
|
如上代码所示,画布会每隔500皮秒捕获并渲染贰回 video
的帧内容(夭寿哇,做完那些动作比非常的大心把饼干洒了一地。。。\(“▔□▔)/):
注意那里大家运用了 canvas.toDataURL 方法来保存帧画面。
接着就是数据解析处理了,大家能够因而对照前后捕获的帧画面来判别视频头是还是不是监察和控制到变化,那么怎么办呢?
熟习设计的同班料定日常使用一个图层功效 —— 混合形式:
当有多少个图层时,对顶层图层设置“差值/Difference”的混杂情势,可以一目驾驭地察看五个图层的差异:
“图A”是本身二〇一八年在铺子楼下拍的相片,然后自身把它有点调亮了一丝丝,并在上头画了二个X 和 O
得到“图B”。接着本身把它们以“差值”情势混合在同步,得到了最右的那张图。
JavaScript
“差值”形式原理:要掺杂图层双方的汉兰达GB值中种种值分别开始展览比较,用高值减去低值作为合成后的水彩,日常用黑灰图层合成一图像时,能够赢得负片效果的反相图像。用紫铜色的话不产生别的改造(深青莲亮度最低,下层颜色减去最小颜色值0,结果和原先一样),而用樱桃红十字会获得反相效果(下层颜色被减去,获得补值),其余颜色则基于它们的亮度水平
1
|
“差值”模式原理:要混合图层双方的RGB值中每个值分别进行比较,用高值减去低值作为合成后的颜色,通常用白色图层合成一图像时,可以得到负片效果的反相图像。用黑色的话不发生任何变化(黑色亮度最低,下层颜色减去最小颜色值0,结果和原来一样),而用白色会得到反相效果(下层颜色被减去,得到补值),其它颜色则基于它们的亮度水平
|
在CSS3中,已经有 blend-mode
天性来支撑那几个风趣的搅拌方式,但是大家开采,在主流浏览器上,canvas
的 globalCompositeOperation 接口也一度可以协理了图像混合情势:
于是乎大家再建多一个画布来突显前后两帧差距:
JavaScript
<video width=”640″ height=”480″ autoplay></video> <canvas
width=”640″ height=”480″></canvas> <canvas width=”640″
height=”480″></canvas> <script> var video =
document.querySelector(‘video’); var canvas =
document.querySelectorAll(‘canvas’)[0]; var canvasForDiff =
document.querySelectorAll(‘canvas’)[1]; // video捕获摄像头画面
navigator.webkitGetUserMedia({ video: true }, success, error); function
success(stream) { video.src = window.UENVISIONL.createObjectU奥迪Q5L(stream);
video.play(); } function error(err) { alert(‘video error: ‘ + err) }
//canvas var context = canvas.getContext(‘二d’), diffCtx =
canvasForDiff.getContext(‘二d’); //将第一个画布混合格局设为“差异”
diffCtx.globalCompositeOperation = ‘difference’; var preFrame, //前一帧
curFrame; //当前帧 //捕获并保存帧内容 function captureAndSaveFrame(){
preFrame = curFrame; context.drawImage(video, 0, 0, 640, 480); curFrame
= canvas.toDataU奇骏L(); //转为base6四并保存 } //绘制base6四图像到画布上
function drawImg(src, ctx){ ctx = ctx || diffCtx; var img = new Image();
img.src = src; ctx.drawImage(img, 0, 0, 640, 480); } //渲染前后两帧差异function renderDiff(){ if(!preFrame || !curFrame) return;
diffCtx.clearRect(0, 0, 640, 480); drawImg(preFrame); drawImg(curFrame);
} //定期捕获 function timer(delta){ setTimeout(function(){
captureAndSaveFrame(); renderDiff(); timer(delta) }, delta || 500); }
timer(); </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
<video width="640" height="480" autoplay></video>
<canvas width="640" height="480"></canvas>
<canvas width="640" height="480"></canvas>
<script>
var video = document.querySelector(‘video’);
var canvas = document.querySelectorAll(‘canvas’)[0];
var canvasForDiff = document.querySelectorAll(‘canvas’)[1];
// video捕获摄像头画面
navigator.webkitGetUserMedia({
video: true
}, success, error);
function success(stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
}
function error(err) {
alert(‘video error: ‘ + err)
}
//canvas
var context = canvas.getContext(‘2d’),
diffCtx = canvasForDiff.getContext(‘2d’);
//将第二个画布混合模式设为“差异”
diffCtx.globalCompositeOperation = ‘difference’;
var preFrame, //前一帧
curFrame; //当前帧
//捕获并保存帧内容
function captureAndSaveFrame(){
preFrame = curFrame;
context.drawImage(video, 0, 0, 640, 480);
curFrame = canvas.toDataURL(); //转为base64并保存
}
//绘制base64图像到画布上
function drawImg(src, ctx){
ctx = ctx || diffCtx;
var img = new Image();
img.src = src;
ctx.drawImage(img, 0, 0, 640, 480);
}
//渲染前后两帧差异
function renderDiff(){
if(!preFrame || !curFrame) return;
diffCtx.clearRect(0, 0, 640, 480);
drawImg(preFrame);
drawImg(curFrame);
}
//定时捕获
function timer(delta){
setTimeout(function(){
captureAndSaveFrame();
renderDiff();
timer(delta)
}, delta || 500);
}
timer();
</script>
|
意义如下(夭寿啊,做完那个动作作者又把Coca Cola洒在键盘上了。。。(#--)/
):
能够看来,当前后两帧差距比十分小时,第10个画布大致是黑乎乎的一片,唯有当拍片头捕获到动作了,第三个画布才有综上说述的高亮内容现身。
由此,大家只供给对第几个画布渲染后的图像进行像素分析——判定其高亮阈值是还是不是达到有个别钦定预期:
JavaScript
var context = canvas.getContext(‘2d’), diffCtx =
canvasForDiff.getContext(‘二d’); //将第四个画布混合格局设为“差距”
diffCtx.globalCompositeOperation = ‘difference’; var preFrame, //前一帧
curFrame; //当前帧 var diffFrame; //存放差距帧的imageData
//捕获并保存帧内容 function captureAndSaveFrame(){ preFrame = curFrame;
context.drawImage(video, 0, 0, 640, 480); curFrame = canvas.toDataUPAJEROL();
//转为base6四并保存 } //绘制base6四图像到画布上 function drawImg(src,
ctx){ ctx = ctx || diffCtx; var img = new Image(); img.src = src;
ctx.drawImage(img, 0, 0, 640, 480); } //渲染前后两帧差别 function
renderDiff(){ if(!preFrame || !curFrame) return; diffCtx.clearRect(0, 0,
640, 480); drawImg(preFrame); drawImg(curFrame); diffFrame =
diffCtx.getImageData( 0, 0, 640, 480 ); //捕获差别帧的imageData对象 }
//计算差距 function calcDiff(){ if(!diffFrame) return 0; var cache =
arguments.callee, count = 0; cache.total = cache.total || 0;
//整个画布都是反革命时怀有像素的值的总和 for (var i = 0, l =
diffFrame.width * diffFrame.height * 4; i < l; i += 4) { count +=
diffFrame.data[i] + diffFrame.data[i + 1] + diffFrame.data[i + 2];
if(!cache.isLoop伊芙r){ //只需在首先次循环里施行 cache.total += 255 * 3;
//单个反革命像素值 } } cache.isLoop伊芙r = true; count *= 三; //亮度放大
//重临“差距画布高亮部分像素总值”占“画布全亮意况像素总值”的比重 return
Number(count/cache.total).toFixed(二); } //定期捕获 function
timer(delta){ setTimeout(function(){ captureAndSaveFrame();
renderDiff(); set提姆eout(function(){ console.log(calcDiff()); }, 10);
timer(delta) }, delta || 500); } timer();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
var context = canvas.getContext(‘2d’),
diffCtx = canvasForDiff.getContext(‘2d’);
//将第二个画布混合模式设为“差异”
diffCtx.globalCompositeOperation = ‘difference’;
var preFrame, //前一帧
curFrame; //当前帧
var diffFrame; //存放差异帧的imageData
//捕获并保存帧内容
function captureAndSaveFrame(){
preFrame = curFrame;
context.drawImage(video, 0, 0, 640, 480);
curFrame = canvas.toDataURL(); //转为base64并保存
}
//绘制base64图像到画布上
function drawImg(src, ctx){
ctx = ctx || diffCtx;
var img = new Image();
img.src = src;
ctx.drawImage(img, 0, 0, 640, 480);
}
//渲染前后两帧差异
function renderDiff(){
if(!preFrame || !curFrame) return;
diffCtx.clearRect(0, 0, 640, 480);
drawImg(preFrame);
drawImg(curFrame);
diffFrame = diffCtx.getImageData( 0, 0, 640, 480 ); //捕获差异帧的imageData对象
}
//计算差异
function calcDiff(){
if(!diffFrame) return 0;
var cache = arguments.callee,
count = 0;
cache.total = cache.total || 0; //整个画布都是白色时所有像素的值的总和
for (var i = 0, l = diffFrame.width * diffFrame.height * 4; i < l; i += 4) {
count += diffFrame.data[i] + diffFrame.data[i + 1] + diffFrame.data[i + 2];
if(!cache.isLoopEver){ //只需在第一次循环里执行
cache.total += 255 * 3; //单个白色像素值
}
}
cache.isLoopEver = true;
count *= 3; //亮度放大
//返回“差异画布高亮部分像素总值”占“画布全亮情况像素总值”的比例
return Number(count/cache.total).toFixed(2);
}
//定时捕获
function timer(delta){
setTimeout(function(){
captureAndSaveFrame();
renderDiff();
setTimeout(function(){
console.log(calcDiff());
}, 10);
timer(delta)
}, delta || 500);
}
timer();
|
瞩目那里我们使用了 count *= 三来放开差距高亮像素的亮度值,否则得出的数值实在太小了。大家运转下页面(图片相当大加载会有点慢):
通过试(xia)验(bai),个人感到若是 calcDiff() 再次回到的比值假使超过0.20,那么就足以定性为“1间空屋子,突然有人闯进来”的景况了。
step四. 上报极度图片
当上述的总计发掘有境况时,必要有某种路子文告大家。有钱有生机的话能够安插个邮件服务器,直接发邮件以致短信公告到温馨,but
本文走的吃吐少年路径,就不搞的那么高档了。
那么要什么轻松地贯彻丰裕图片的举报呢?小编暂且想到的是 ——
直接把难题图片发送到某些站点中去。
此处大家接纳搜狐的“日记”成效,它能够专断上传相关内容。
JavaScript
p.s.,其实那里原本是想一向把图纸传遍天涯论坛相册上的,可惜POST请求的图片实体供给走
file 格式,即不或者透过脚本更换文件的 input[type=file],转 Blob
再上传也没用,只可以作罢。
1
|
p.s.,其实这里原本是想直接把图片传到博客园相册上的,可惜POST请求的图片实体要求走 file 格式,即无法通过脚本更改文件的 input[type=file],转 Blob 再上传也没用,只好作罢。
|
咱俩在治本后台创立日记时,通过 Fiddler 抓包能够见见其请求参数格外轻松:
故此得以一向协会一个伸手:
JavaScript
//极度图片上传管理 function submit(){ //ajax 提交form $.ajax({ url :
”, type : “POST”, data : {
‘__VIEWSTATE’: ”, ‘__VIEWSTATEGENERATOR’: ‘4773056F’,
‘Editor$Edit$txbTitle’: ‘告警’ + Date.now(), ‘Editor$Edit$EditorBody’:
‘<img src=”‘ + curFrame + ‘” />’, ‘Editor$Edit$lkbPost’: ‘保存’ },
success: function(){ console.log(‘submit done’) } }); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//异常图片上传处理
function submit(){
//ajax 提交form
$.ajax({
url : ‘http://i.cnblogs.com/EditDiary.aspx?opt=1’,
type : "POST",
data : {
‘__VIEWSTATE’: ”,
‘__VIEWSTATEGENERATOR’: ‘4773056F’,
‘Editor$Edit$txbTitle’: ‘告警’ + Date.now(),
‘Editor$Edit$EditorBody’: ‘<img src="’ + curFrame + ‘" />’,
‘Editor$Edit$lkbPost’: ‘保存’
},
success: function(){
console.log(‘submit done’)
}
});
}
|
当然要是请求页面跟今日头条域名分化,是无力回天发送 cookie
导致请求跨域而失效,可是这几个很好解决,直接改动 host
就能够(怎么修改就不介绍了,自行百度吗)。
本人那边改完 host,通过
的地点访问页面,发现录制头竟然失效了~
通过谷歌(谷歌)的文书档案可以识破,那是为了安全性思虑,非
HTTPS 的服务端请求都无法接通录像头。不过解决办法也是一些,以 window
系统为例,展开 cmd 命令行面板并牢固到 chrome 安装文件夹下,然后实践:
ZSH
chrome
–unsafely-treat-insecure-origin-as-secure=””
–user-data-dir=C:\testprofile
1
|
chrome –unsafely-treat-insecure-origin-as-secure="http://i.cnblogs.com/h5monitor/final.html" –user-data-dir=C:\testprofile
|
此举将以沙箱情势打开三个单身的 chrome
进度,并对点名的站点去掉安全范围。注意我们在新开的 chrome
中得重新登陆天涯论坛。
那时便能平常访问录像头了,大家对代码做下管理,当差距检查实验开掘极度时,创设一份日记,最小间隔时间为五秒(可是后来发觉没须要,因为今日头条已经有做了时光范围,大约十秒后技巧公布新的日记):
JavaScript
//定时捕获 function timer(delta){ set提姆eout(function(){
captureAndSaveFrame(); renderDiff(); if(calcDiff() > 0.二){
//监察和控制到丰裕,发日志 submit() } timer(delta) }, delta || 500); }
setTimeout(timer, 40000 * 10); //设定张开页面10分钟后才开头监察和控制//非常图片上传处理 function submit(){ var cache = arguments.callee, now
= Date.now(); if(cache.reqTime && (now – cache.reqTime < 6000))
return; //日记创立最小间隔为五秒 cache.reqTime = now; //ajax 提交form
$.ajax({ url : ”, type :
“POST”, timeout : 5000, data : { ‘__VIEWSTATE’: ”,
‘__VIEWSTATEGENERATOR’: ‘4773056F’, ‘Editor$Edit$txbTitle’: ‘告警’ +
Date.now(), ‘Editor$Edit$EditorBody’: ‘<img src=”‘ + curFrame + ‘”
/>’, ‘Editor$Edit$lkbPost’: ‘保存’ }, success: function(){
console.log(‘submit done’) }, error: function(err){ cache.reqTime = 0;
console.log(‘error: ‘ + err) } }); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
//定时捕获
function timer(delta){
setTimeout(function(){
captureAndSaveFrame();
renderDiff();
if(calcDiff() > 0.2){ //监控到异常,发日志
submit()
}
timer(delta)
}, delta || 500);
}
setTimeout(timer, 60000 * 10); //设定打开页面十分钟后才开始监控
//异常图片上传处理
function submit(){
var cache = arguments.callee,
now = Date.now();
if(cache.reqTime && (now – cache.reqTime < 5000)) return; //日记创建最小间隔为5秒
cache.reqTime = now;
//ajax 提交form
$.ajax({
url : ‘http://i.cnblogs.com/EditDiary.aspx?opt=1’,
type : "POST",
timeout : 5000,
data : {
‘__VIEWSTATE’: ”,
‘__VIEWSTATEGENERATOR’: ‘4773056F’,
‘Editor$Edit$txbTitle’: ‘告警’ + Date.now(),
‘Editor$Edit$EditorBody’: ‘<img src="’ + curFrame + ‘" />’,
‘Editor$Edit$lkbPost’: ‘保存’
},
success: function(){
console.log(‘submit done’)
},
error: function(err){
cache.reqTime = 0;
console.log(‘error: ‘ + err)
}
});
}
|
实行成效:
日记也是妥妥的出来了:
点开就能观看那么些的那张图纸了:
要注意的是,天涯论坛对日记发布数据是有做每天额度限制来防刷的,抵达限额的话会招致当天的小说和作品也无从发表,所以得严刻运用:
然而那种格局仅能反映格外图片,暂且不恐怕让咱们立即收悉告警,风趣味的童鞋可以试着再写个
chrome 插件,按时去拉取日记列表做剖断,假诺有新增添日记则触发页面 alert。
别的大家自然期待能一向对闯入者举办警示,那块比较好办 ——
搞个警示的节拍,在那三个的时候接触播放就可以:
JavaScript
//播放音频 function fireAlarm(){ audio.play() } //定时捕获 function
timer(delta){ setTimeout(function(){ captureAndSaveFrame(); if(preFrame
&& curFrame){ renderDiff(); if(calcDiff() > 0.2){ //监控到十二分//发日记 submit(); //播放音频告警 fireAlarm(); } } timer(delta) }, delta
|| 500); } setTimeout(timer, 50000 * 拾);
//设定展开页面10分钟后才初步监察和控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//播放音频
function fireAlarm(){
audio.play()
}
//定时捕获
function timer(delta){
setTimeout(function(){
captureAndSaveFrame();
if(preFrame && curFrame){
renderDiff();
if(calcDiff() > 0.2){ //监控到异常
//发日记
submit();
//播放音频告警
fireAlarm();
}
}
timer(delta)
}, delta || 500);
}
setTimeout(timer, 60000 * 10); //设定打开页面十分钟后才开始监控
|
提及底说一下,本文代码均挂在我的github上,有意思味的童鞋能够自助下载。共勉~
1 赞 4 收藏 4
评论
大家领略,通过为静态能源设置Cache-Control
和Expires
响应头,能够迫使浏览器对其开始展览缓存。浏览器在向后台发起呼吁的时候,会先在自己的缓存里面找,假若缓存里面未有,才会继续向服务器请求这些静态财富。利用那一点,我们能够把壹部分必要被缓存的消息经过那么些静态财富缓存机制来开始展览仓库储存。
那正是说大家怎么把音信写入到静态能源中呢?canvas
提供了.getImageData()方法和.createImageData()方式,能够分别用于读取和设置图片的rgba
值。所以大家得以行使那八个API实行音信的读写操作。
接下去看规律图:
当静态能源进入缓存,今后的别样对于该图形的乞请都会先物色本地缓存,也正是说新闻实际早就以图表的款型被缓存到地头了。
注意,由于rgba
值只好是[0,
255]以内的平头,所以本文所斟酌的点子仅适用于纯数字组合的数额。
* Xshell 使用open张开多个虚拟机;
创打败务器
先是要引进http模块
var http = require(“http”);
通过
http.createServer() 方法创立服务器
demo:
var http = require(‘http’);http.createServer(function (request,
response) { // 发送 HTTP 尾部 // HTTP 状态值: 200 : OK // 内容类型:
text/plain response.writeHead(200, {‘Content-Type’: ‘text/plain’}); //
发送响应数据 “Hello World” response.end(‘Hello
World\n’);}).listen(8888);// 终端打字与印刷如下新闻console.log(‘Server
running at ‘);
写入数据足以行使write()
response.write(“Hello World”);
response.write(” IAM LQ”);
response.write(data.toString());
response.end();
咱俩应用node
搭建一个简短的静态服务器:
JavaScript
const fs = require(‘fs’) const http = require(‘http’) const url =
require(‘url’) const querystring = require(‘querystring’) const util =
require(‘util’) const server = http.createServer((req, res) => { let
pathname = url.parse(req.url).pathname let realPath = ‘assets’ +
pathname console.log(realPath) if (realPath !== ‘assets/upload’) {
fs.readFile(realPath, “binary”, function(err, file) { if (err) {
res.writeHead(500, {‘Content-Type’: ‘text/plain’}) res.end(err) } else {
res.writeHead(200, { ‘Access-Control-Allow-Origin’: ‘*’,
‘Content-Type’: ‘image/png’, ‘ETag’: “666666”, ‘Cache-Control’: ‘public,
max-age=31536000’, ‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’ })
res.write(file, “binary”) res.end() } }) } else { let post = ”
req.on(‘data’, (chunk) => { post += chunk }) req.on(‘end’, () => {
post = querystring.parse(post) console.log(post.imgData)
res.writeHead(200, { ‘Access-Control-Allow-Origin’: ‘*’ }) let
base64Data = post.imgData.replace(/^data:image\/\w+;base64,/, “”) let
dataBuffer = new Buffer(base64Data, ‘base64’)
fs.writeFile(‘assets/out.png’, dataBuffer, (err) => { if (err) {
res.write(err) res.end() } res.write(‘OK’) res.end() }) }) } })
server.listen(80) console.log(‘Listening on port: 80’)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
const fs = require(‘fs’)
const http = require(‘http’)
const url = require(‘url’)
const querystring = require(‘querystring’)
const util = require(‘util’)
const server = http.createServer((req, res) => {
let pathname = url.parse(req.url).pathname
let realPath = ‘assets’ + pathname
console.log(realPath)
if (realPath !== ‘assets/upload’) {
fs.readFile(realPath, "binary", function(err, file) {
if (err) {
res.writeHead(500, {‘Content-Type’: ‘text/plain’})
res.end(err)
} else {
res.writeHead(200, {
‘Access-Control-Allow-Origin’: ‘*’,
‘Content-Type’: ‘image/png’,
‘ETag’: "666666",
‘Cache-Control’: ‘public, max-age=31536000’,
‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’
})
res.write(file, "binary")
res.end()
}
})
} else {
let post = ”
req.on(‘data’, (chunk) => {
post += chunk
})
req.on(‘end’, () => {
post = querystring.parse(post)
console.log(post.imgData)
res.writeHead(200, {
‘Access-Control-Allow-Origin’: ‘*’
})
let base64Data = post.imgData.replace(/^data:image\/\w+;base64,/, "")
let dataBuffer = new Buffer(base64Data, ‘base64’)
fs.writeFile(‘assets/out.png’, dataBuffer, (err) => {
if (err) {
res.write(err)
res.end()
}
res.write(‘OK’)
res.end()
})
})
}
})
server.listen(80)
console.log(‘Listening on port: 80’)
|
以此静态财富的功力很简单,它提供了三个功能:通过客户端传来的base6四生成图片并保留到服务器;设置图片的缓存时间并发送到客户端。
根本部分是设置响应头:
JavaScript
res.writeHead(200, { ‘Access-Control-Allow-Origin’: ‘*’,
‘Content-Type’: ‘image/png’, ‘ETag’: “666666”, ‘Cache-Control’: ‘public,
max-age=31536000’, ‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’ })
1
2
3
4
5
6
7
|
res.writeHead(200, {
‘Access-Control-Allow-Origin’: ‘*’,
‘Content-Type’: ‘image/png’,
‘ETag’: "666666",
‘Cache-Control’: ‘public, max-age=31536000’,
‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’
})
|
大家为这张图纸设置了一年的Content-Type
和10年的Expires
,理论上丰裕长了。上面大家来展开客户端的coding。
* linux 中创建多个空白的日志文件用touch命令;
使用package.json
npm init 去创建
XHTML
<!– client.html –> <canvas id=”canvas” width=”8″,
height=”1″></canvas>
1
2
3
|
<!– client.html –>
<canvas id="canvas" width="8", height="1"></canvas>
|
举个例子我们必要仓库储存的是3一人的多寡,所以我们为canvas设置宽度为8,中度为一。到底干什么32人数据对应长度为八,是因为每贰个像素都有四个rgba
,对应着red
,green
,blue
和alpha
五个数值,所以需求除以肆。
JavaScript
<!– client.js –> let keyString =
‘01234567890123456789012345678901’ let canvas =
document.querySelector(‘#canvas’) let ctx = canvas.getContext(‘2d’) let
imgData = ctx.createImageData(8, 1) for (let i = 0; i <
imgData.data.length; i += 4) { imgData.data[i + 0] =
parseInt(keyString[i]) + 50 imgData.data[i + 1] =
parseInt(keyString[i + 1]) + 100 imgData.data[i + 2] =
parseInt(keyString[i + 2]) + 150 imgData.data[i + 3] =
parseInt(keyString[i + 3]) + 200 } ctx.putImageData(imgData, 0, 0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!– client.js –>
let keyString = ‘01234567890123456789012345678901’
let canvas = document.querySelector(‘#canvas’)
let ctx = canvas.getContext(‘2d’)
let imgData = ctx.createImageData(8, 1)
for (let i = 0; i < imgData.data.length; i += 4) {
imgData.data[i + 0] = parseInt(keyString[i]) + 50
imgData.data[i + 1] = parseInt(keyString[i + 1]) + 100
imgData.data[i + 2] = parseInt(keyString[i + 2]) + 150
imgData.data[i + 3] = parseInt(keyString[i + 3]) + 200
}
ctx.putImageData(imgData, 0, 0)
|
率先我们借使需求被缓存的字符串为叁十几个人的01234567890123456789012345678901
,然后我们选取.createImageData(8, 1)
转移1个空手的imgData对象。接下来,我们对那些空对象开展赋值。为了试验效果更直观,大家对rgba
值都开始展览了加大。设置完了imgData
以后,通过.putImageData()
主意把它放入大家的canvas就能够。
笔者们前天得以打字与印刷一下,看看那么些imgData
是什么:
JavaScript
// console.log(imgData.data) [50, 101, 152, 203, 54, 105, 156, 207, 58,
109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203,
54, 105, 156, 207, 58, 109, 150, 201]
1
2
3
|
// console.log(imgData.data)
[50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201]
|
接下去,我们要把这些canvas编写翻译为一张图纸的base6四并发送给服务器,同时吸收服务器的响应,对图纸张开缓存:
JavaScript
$.post(”, { imgData: canvas.toDataURL() },
(data) => { if (data === ‘OK’) { let img = new Image()
img.crossOrigin = “anonymous” img.src = ”
img.onload = () => { console.log(‘落成图片请求与缓存’)
ctx.drawImage(img, 0, 0) console.log(ctx.getImageData(0, 0, 捌, 1).data)
} } })
1
2
3
4
5
6
7
8
9
10
11
12
|
$.post(‘http://xx.xx.xx.xx:80/upload’, { imgData: canvas.toDataURL() }, (data) => {
if (data === ‘OK’) {
let img = new Image()
img.crossOrigin = "anonymous"
img.src = ‘http://xx.xx.xx.xx:80/out.png’
img.onload = () => {
console.log(‘完成图片请求与缓存’)
ctx.drawImage(img, 0, 0)
console.log(ctx.getImageData(0, 0, 8, 1).data)
}
}
})
|
代码不会细小略,通过.toDataURL()
办法把base6四发送到服务器,服务器管理后生成图片并回到,其图片能源地址为http://xx.xx.xx.xx:80/out.png
。在img.onload
后,其实图片就曾经变成了地面缓存了,大家在这些事件个中把图片音信打字与印刷出来,作为和源数据的对照。
* http 是nodejs的服务模块
Node.js REPL交互式解释器
http://www.runoob.com/nodejs/nodejs-repl.html
张开服务器,运行客户端,第三回加载的时候经过调节台能够见见响应的图样音信:
200 OK
,注脚是从服务端获取的图形。
关门当前页面,重新载入:
200 OK (from cache)
,表明是从本地缓存读取的图样。
接下去间接看rgba
值的对峙统一:
源数据: [50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52,
103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207,
58, 109, 150, 201] 缓存数据:[50, 100, 152, 245, 54, 105, 157, 246,
57, 109, 149, 244, 52, 103, 154, 245, 56, 107, 157, 247, 50, 100, 152,
245, 54, 105, 157, 246, 57, 109, 149, 244]
1
2
3
|
源数据: [50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201]
缓存数据:[50, 100, 152, 245, 54, 105, 157, 246, 57, 109, 149, 244, 52, 103, 154, 245, 56, 107, 157, 247, 50, 100, 152, 245, 54, 105, 157, 246, 57, 109, 149, 244]
|
可以看到,源数据与缓存数据**基本一致**,在`alpha`值的误差偏大,在`rgb`值内**偶有误差**。通过分析,认为产生误差的原因是服务端在进行base64转buffer的过程中,所涉及的运算会导致数据的改变,这一点**有待考证**。
事先得到的下结论,源数据与缓存数据存在测量误差的因由,经调研后鲜明为alpha
值的干扰所致。如果大家把alpha
值直接定为255,并且只把数量存放在rgb
值内部,就可以消除引用误差。上面是革新后的结果:
源数据: [0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7,
8, 255, 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255] 缓存数据:[0, 1, 2,
255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7, 8, 255, 0, 1, 2,
255, 4, 5, 6, 255, 8, 9, 0, 255]
1
2
3
|
源数据: [0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7, 8, 255, 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255]
缓存数据:[0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255, 2, 3, 4, 255, 6, 7, 8, 255, 0, 1, 2, 255, 4, 5, 6, 255, 8, 9, 0, 255]
|
因为笔者懒,只是把alpha
值给定为255而并未有把循环赋值的逻辑实行革新,所以第5n位的元数据被向来替换到了25五,那个留着读者自行修改没事再改……
综合,那一个动用png图的rgba值缓存数据的黑科技(science and technology),在答辩上是可行的,但是在实际操作过程中可能还要考虑更多的影响因素,比如设法消除服务端的误差,采取容错机制等。实则也是实惠的。
值得注意的是,localhost
兴许默许会直接通过地方而不是服务器请求财富,所以在本地实验中,能够通过安装header进行cors
跨域,并且通过安装IP地址和80端口模拟服务器访问。
* fs 是文本服务器模块
Nodejs 回调函数
demo:
var http=require(‘http’);//http服务
var fs = require(“fs”);//读取文件
http.createServer(function(request,response){
response.writeHead(200,{‘Content-Type’:’text/plain’});
//读取文件消息 将赶回值 给response
//var data = fs.readFileSync(‘input.txt’); 这种方法 是 同步
fs.readFile(‘message.txt’, function (err, data) {
if (err) return console.error(err);
response.end(data.toString());
});
}).listen(8888);
说是黑科技(science and technology),其实原理分外轻便,与之类似的还有通过Etag
等艺术开始展览强缓存。斟酌的目标只是为了求学,千万不要看成地下之用。要是读者们发掘那篇小说有如何错漏之处,接待指正,也冀望有意思味的心上人能够一同打开切磋。
谢谢你的开卷。笔者是Jrain,应接关切本身的特辑,将不按时分享自身的求学体验,开采心得,搬运墙外的干货。下次见啦!
1 赞 2 收藏 1
评论
* url是url路由模块
console.log(‘运行在
http://localhost:”8888’);
2.创建nodejs服务器;
Nodejs 事件循环
绑定和监听事件 供给引入events 模块 并且通过伊夫ntEmitter
类来绑定和监听事件
eventEmitter.on(‘你起的名字’,function(){
//那里是以此事件对应的do something
})
eventEmitter.emit(‘你起的名字’);//这样子去施行你写好的风云
//定义主机IP常量名称
demo:
// 引入 events 模块
var events = require(‘events’);
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
const ip = ‘192.168.0.102’;
//制造链接函数
eventEmitter.on(‘connection’,function(){
console.log(‘链接成功’);
eventEmitter.emit(‘data_received’);
});
//定义端口号
// 使用无名氏函数绑定 data_received 事件
eventEmitter.on(‘data_received’, function(){
console.log(‘数据接受成功。’);
});
const port = 2000;
// 触发 connection 事件
eventEmitter.emit(‘connection’);
//引进的组装模块 http、url、fs
console.log(“程序实践实现。”);
const http = require(‘http’);
Buffer缓冲区
专门存放二进制数据
new Buffer成立buffer对象实例 write再次回到实际写入的轻重缓急
写入demo:
var buf = new Buffer(256);
var len =
buf.write(“www.runoob.cn”,0,八,”utf八”);//数据,起始下标,能存多少位,编码格局
const url = require(‘url’);
console.log(“写入字节数 : “+ len);//八
存入男人并且打字与印刷出来:
var buf = new Buffer(‘你好笔者是数据’);
const fs = require(‘fs’);
console.log(buf.toString());
合并buffer:
var buffer1 = new Buffer(‘新手教程 ‘);var buffer二 = new
Buffer(‘www.runoob.com’);var;var)
buffer3 = Buffer.concat([buffer1,buffer2]);console.log(“buffer3 内容:
” + buffer3.toString());
//创立1个劳务
Node.js Stream(流)
http 服务器发起呼吁的request 对象就是八个 Stream
var server = http.createServer(function(req,res){
createWriteStream//写入流
createReadStream//读取流
创立对象并且针对文件对象
var readerStream = fs.createReadStream(‘input.txt’);
var writerStream = fs.createWriteStream(‘output.txt’);
写入数据 并且定义编码典型
var data=’我是写入的数据’
writerStream.write(data,’UTF8′);
读取数据并且打字与印刷
// 设置编码为 utf8。
var data=”;
readerStream.setEncoding(‘utf8’);
// 读取数据并且打字与印刷
readerStream.on(‘data’, function(data) {
data = data;
console.log(data);
});
以下是数码copy 一个文件读取存入另四个文件
var fs = require(“fs”);
res.writeHead(200,{‘Content-Type’:’text/plain’});
// 创建1个可读流
var readerStream = fs.createReadStream(‘message.txt’);
res.write(‘my nodejs’);
// 创造2个可写流
var writerStream = fs.createWriteStream(‘book.txt’);
res.end();
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);
});
console.log(“程序试行达成”);
压缩文件
var fs = require(“fs”);var zlib = require(‘zlib’);// 压缩 input.txt
文件为 input.txt.gzfs.createReadStream(‘input.txt’)
.pipe(zlib.createGzip()) .pipe(fs.createWriteStream(‘input.txt.gz’));
console.log(“文件减弱达成。”);
解压文件
var fs = require(“fs”);var zlib = require(‘zlib’);// 解压 input.txt.gz
文件为 input.txtfs.createReadStream(‘input.txt.gz’)
.pipe(zlib.createGunzip()) .pipe(fs.createWriteStream(‘input.txt’));
console.log(“文件解压完结。”);
//监听七个端口
nodejs 模块系统
事先加载原生模块 举例http、fs、path等
var http=require(‘http’);
module.exports=function(){} or 对象
server.listen(port,ip,function(){
Nodejs函数
和JS一样
console.log(‘server start’);
nodejs路由
大家必要的装有数据都会含有在request对象中,该目的作为onRequest()回调函数的首先个参数字传送递。可是为精晓析这一个多少,我们须求额外的Node.JS模块,它们分别是url和querystring模块。
简轻松单就是路线
var pathname =
url.parse(‘http://baidu.com/a/b?a=1’).pathname.pathname);
var
router=url.parse(‘http://baidu.com/a/b?a=1’).query.query)
response.write(pathname+” “+router);
});
会出现 /a/b a=1
三.收获U牧马人L部分块的内容 url;
node全局对象
response.write(__filename);D:\nodejsdemo\global.js
response.write(__dirname);D:\nodejsdemo
setTimeout(cb, ms)
clearTimeout(t)
setInterval(cb, ms)
console
process process 是1个全局变量,即 global 对象的质量。 和体系互相要用到
const ip = ‘192.168.1.118’;//主机IP
nodejs常用工具 util
util 是多个Node.js 核心模块,提供常用函数的会合,用于弥补宗旨JavaScript
的效益 过于精简的供不应求。
用于后续
util.inherits(child,parent)
唯其如此继续原型中定义的函数 即因而prototype扩张的函数
构造函数内部创造的不继续
util.inspect肆意对象调换为字符串的章程,平常用于调节和测试和错误输出。它至少接受三个参数
object,即要调换的对象。
util.isArray(object)假如给定的参数 “object”
是贰个数组重回true,不然再次回到false。
util.isRegExp(object)假诺给定的参数 “object”
是二个正则表明式重回true,不然再次来到false。
util.isDate(object)假如给定的参数 “object”
是二个日子重临true,不然再次回到false。
util.isError(object)假诺给定的参数 “object”
是3个荒谬对象回来true,不然重回false。
const port = 2001;//端口号
选拔框架Express
安装:npm install express –save
以下多少个首要的模块要求与express一起安装:
$ npm install body-parser –save$ npm install cookie-parser –save$ npm
install multer –save
body-parser 管理JSON RAW Text UPRADOL编码的数量
cookie-parser解析cookie的工具 通过req.cookies 能够取到传来的cookie
转成对象
multer 处理enctype=”multpart/form-data”的表单数据
demo: 那里配置路由
var express=require(‘express’);
var app=express();
app.get(‘/’,function(req,res){
res.send(‘HELLO WORD2’);
})
app.get(‘/app’,function(req,res){
res.send(‘进入了另3个路线’);
})
var server=app.listen(8888,function(){
var host=server.address().address
var port=server.address().port
console.log(“应用实例,访问地址为 http://”, host, port)
})
静态能源
app.use(express.static(‘public’))
http://localhost:8888/img/2.png
就不要写public了
//引进的组装模块 http、url、fs
设置路由 编写接口
var express=require(‘express’);
var app=express();
//静态文件
app.use(express.static(‘public’))
//设置默许入口
app.get(‘/’,function(req,res){
res.sendFile(__dirname+”/”+”index.html”);
})
//接口
app.get(‘/message’,function(req,res){
res.writeHead(200,{‘Content-Type’:’text/html;charset=utf-8′});//设置response编码为utf-8
obj={
id:req.query.id,
name:req.query.name
}
res.end(JSON.stringify(obj));
})
var server=app.listen(8888,function(){
var host=server.address().address
var port=server.address().port
console.log(“应用实例,访问地址为 http://”, host, port)
})
const http = require(‘http’);
Post的demo:必须求引进body-parser 供给设置依赖
var urlencodedParser = bodyParser.urlencoded({ extended: false })
是必须的
var express=require(‘express’);
var app=express();
var bodyParser = require(‘body-parser’);
// 创立 application/x-www-form-urlencoded 编码解析
var urlencodedParser = bodyParser.urlencoded({ extended: false })
//静态文件
app.use(express.static(‘public’))
//设置默许入口
app.get(‘/’,function(req,res){
res.sendFile(__dirname+”/”+”post.html”);
})
//接口
app.post(‘/message’,urlencodedParser,function(req,res){
res.writeHead(200,{‘Content-Type’:’text/html;charset=utf-8′});//设置response编码为utf-8
obj={
id:req.body.id,
name:req.body.name
}
res.end(JSON.stringify(obj));
})
var server=app.listen(8888,function(){
var host=server.address().address
var port=server.address().port
console.log(“应用实例,访问地址为 http://”, host, port)
})
const url = require(‘url’);
const fs = require(‘fs’);
//创设服务的回掉函数
var funSer = function(req,res){
//获取url地址块的剧情 如:/path/show
var parth = url.parse(req.url).pathname;
res.write(parth);
res.end();
}
//监听端口的回掉
var fun = function(){
console.log(‘server start’);
}
var server = http.createServer(funSer).listen(port,ip,fun);
四.读取文件的始末 File System;
const ip = ‘192.168.1.118’;//主机IP
const port = 2001;//端口号
//引进的组建立模型块 http、url、fs
const http = require(‘http’);
const url = require(‘url’);
const fs = require(‘fs’);
//真正打字与印刷文件内容
fs.readFile(‘./index.html’, (err, data) => {
if (err) throw err;
//打印字符串内容
console.log(data.toString());
});
//成立服务的回掉函数
var funSer = function(req,res){
//获取url地址块的始末 如:/path/show
var parth = url.parse(req.url).pathname;
res.write(parth);
res.end();
}
//监听端口的回掉
var fun = function(){
console.log(‘server start’);
}
var server = http.createServer(funSer).listen(port,ip,fun);
const ip = ‘192.168.1.118’;//主机IP
const port = 2001;//端口号
//引入的组建立模型块 http、url、fs
const http = require(‘http’);
const url = require(‘url’);
const fs = require(‘fs’);
//实例化二个劳务容器
var server = new http.Server();
//监听二个端口
server.listen(port , ip);
//注册2个事件管理的on方法
server.on(‘request’ , function(req , res){
//获取请求的url地址
var url = urls.parse(req.url);
//console.log(url.pathname);
//遵照path路线来读取分裂的沙盘文件
switch( url.pathname ){
case ” || ‘/’:
//读取文件内容
fs.readFile(‘./index.html’,function( error, content){
if(error){//要是有错误时,展现错误音讯
res.writeHead(400,{‘Content-Type’:’text/plain;charset=”utf-8″‘});
res.write(error.message);
res.end();
威尼斯人线上娱乐 ,}else{
//正确时浏览器输出模板文件的内容
res.writeHead(200,{‘Content-Type’:’text/html;charset=”utf-8″‘});//头信息
res.write(content);//模板文件内容
res.end();
}
});
break;
case ‘/list’:
fs.readFile(‘./list.html’,function( error, content){
if(error){
res.writeHead(400,{‘Content-Type’:’text/plain;charset=”utf-8″‘});
res.write(error.message);
res.end();
}else{
res.writeHead(200,{‘Content-Type’:’text/html;charset=”utf-8″‘});
res.write(content);
res.end();
}
});
break;
case ‘/show’:
fs.readFile(‘./show.html’,function( error, content){
if(error){
res.writeHead(400,{‘Content-Type’:’text/plain;charset=”utf-8″‘});
res.write(error.message);
res.end();
}else{
res.writeHead(200,{‘Content-Type’:’text/html;charset=”utf-8″‘});
res.write(content);
res.end();
}
});
break;
default:
fs.readFile(‘./default.html’,function( error, content){
if(error){
res.writeHead(400,{‘Content-Type’:’text/plain;charset=”utf-8″‘});
res.write(error.message);
res.end();
}else{
res.writeHead(200,{‘Content-Type’:’text/html;charset=”utf-8″‘});
res.write(content);
res.end();
}
});
break;
}
});