研商前端黑科学技术——通过 png 图的 rgba 值缓存数据

2016/09/12 · JavaScript
· 1 评论 ·
缓存

原来的作品出处: jrainlau   

谈到前端缓存,超过一半人想到的独自是多少个常常的方案,比方cookielocalStoragesessionStorage,只怕增多indexedDBwebSQL,以及manifest研究前端黑科学技术,来看望机智的前端童鞋怎么防盗。离线缓存。除却,到底还有未有其他办法能够开展前端的数据缓存呢?那篇小说将会带您1只来探索,如何一步一步地经过png图的rgba值来缓存数据的黑科学和技术之旅。

一.小知识点总结

Node.js
是单进度单线程应用程序,然则经过事件和回调辅助并发,所以品质非常高。
nodejs由以下模块组合:
引进 required 模块:大家得以应用 require 指令来载入 Node.js 模块。
成立服务器:服务器能够监听客户端的伸手,类似于 Apache 、Nginx 等 HTTP
服务器。
收下请求与响应请求 服务器很轻易创设,客户端能够选择浏览器或终点发送 HTTP
请求,服务器收到请求后回去响应数据。

来探视机智的前端童鞋怎么防盗

2016/07/12 · JavaScript
· 4 评论 ·
HTML5

初稿出处: VaJoy   

许多花费的童鞋都是寥寥混江湖、夜宿城中村,假若居住的地点安保欠缺,那么出门在外难免思量屋里的财产安全。

实质上世面上有繁多光辉上的防盗设备,但对此灵动的前端童鞋来说,只要有一台附带录像头的计算机,就足以省略地达成二个防盗监察和控制系统~

纯 JS 的“防盗”技艺相当的大程度借助于 H5 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> 上看到拍戏头捕获到的镜头了:

金沙注册送58 1

step2. 捕获 video 帧画面

只然而开着录制头监视房间可不曾此外意义,浏览器不会帮你对监督画面进行辨析。所以这边大家胜利动用脚本捕获
video 上的帧画面,用于在此起彼伏进展数量解析。

从此间开端大家将在借助 canvas
力量了。在 Canvas入门(五)一文大家介绍过 ctx.drawImage()
方法,通过它能够捕获 video 帧画面并渲染到画布上。

笔者们需求创设2个画布,然后这么写:

JavaScript

金沙注册送58,<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.webkitU冠道L.createObjectUQashqaiL(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>

如上代码所示,五秒后把录制帧内容渲染到画布上(下方右图)

金沙注册送58 2

step叁. 对抓获的三个帧画面施行差异混合

在上面我们提到过,要有效地辨认有些场景,要求对录像画面实行数据解析。

那正是说要怎么辨识我们的房舍是不是有人忽然闯入了吗?答案很简短 —— 定期地破获
video 画面,然后相比较前后两帧内容是或不是存在一点都不小变迁。

小编们先轻松地写二个定时捕获的点子,并将捕获到的帧数据存起来:

JavaScript

//canvas var context = canvas.getContext(‘贰d’); var preFrame, //前一帧
curFrame; //当前帧 //捕获并保存帧内容 function captureAndSaveFrame(){
console.log(context); preFrame = curFrame; context.drawImage(video, 0,
0, 640, 480); curFrame = canvas.toDataULacrosseL; //转为base6四并保存 }
//定期捕获 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
的帧内容(夭寿哇,做完这一个动作不小心把饼干洒了壹地。。。\(“▔□▔)/)

金沙注册送58 3

瞩目那里大家利用了 canvas.toDataURL 方法来保存帧画面。

接着便是数据解析管理了,咱们能够通过相比较前后捕获的帧画面来决断录像头是或不是监察和控制到变化,那么如何是好吧?

深谙设计的同桌肯定平常使用三个图层效用 —— 混合情势:

金沙注册送58 4

当有五个图层时,对顶层图层设置“差值/Difference”的交集形式,能够看清地看到多少个图层的差距:

金沙注册送58 5

“图A”是作者二零一八年在店堂楼下拍的相片,然后本身把它有点调亮了一丝丝,并在地点画了3个X 和 O
获得“图B”。接着自身把它们以“差值”格局混合在1块,得到了最右的那张图。

JavaScript

“差值”形式原理:要掺杂图层双方的EnclaveGB值中种种值分别开始展览比较,用高值减去低值作为合成后的水彩,经常用水晶色图层合成1图像时,能够得到负片效果的反相图像。用莲红的话不产生别的变动(青黑亮度最低,下层颜色减去最小颜色值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.U奥迪Q伍L.createObjectU中华VL(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, //前1帧
curFrame; //当前帧 //捕获并保存帧内容 function captureAndSaveFrame(){
preFrame = curFrame; context.drawImage(video, 0, 0, 640, 480); curFrame
= canvas.toDataULX570L(); //转为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>

作用如下(夭寿啊,做完那些动作我又把Pepsi-Cola洒在键盘上了。。。(#--)/

金沙注册送58 6

能够看到,当前后两帧差别不大时,第多个画布大致是模糊的一片,只有当拍摄头捕获到动作了,首个画布才有显明的高亮内容出现。

之所以,大家只须求对首个画布渲染后的图像实行像素分析——判定其高亮阈值是或不是达到有些钦赐预期:

JavaScript

var context = canvas.getContext(‘二d’), diffCtx =
canvasForDiff.getContext(‘二d’); //将第一个画布混合情势设为“差别”
diffCtx.globalCompositeOperation = ‘difference’; var preFrame, //前1帧
curFrame; //当前帧 var diffFrame; //存放差别帧的imageData
//捕获并保存帧内容 function captureAndSaveFrame(){ preFrame = curFrame;
context.drawImage(video, 0, 0, 640, 480); curFrame = canvas.toDataUSportageL();
//转为base6四并保存 } //绘制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.isLoop伊夫r){ //只需在率先次循环里实施 cache.total += 25伍 * 叁;
//单个反革命像素值 } } cache.isLoop伊夫r = true; count *= 三; //亮度放大
//再次来到“差距画布高亮部分像素总值”占“画布全亮意况像素总值”的百分比 return
Number(count/cache.total).toFixed(二); } //定期捕获 function
timer(delta){ setTimeout(function(){ captureAndSaveFrame();
renderDiff(); setTimeout(function(){ console.log(calcDiff()); }, 十);
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 *= 三来加大差距高亮像素的亮度值,不然得出的数值实在太小了。大家运维下页面(图片异常的大加载会有点慢)

金沙注册送58 7

透过试(xia)验(bai),个人以为只要 calcDiff() 重返的比率借使超过0.20,那么就足以定性为“一间空屋子,突然有人闯进来”的情形了。

step四. 上报卓殊图片

当上述的乘除开掘有场景时,必要有某种渠道布告我们。有钱有精力的话能够布置个邮件服务器,直接发邮件以致短信通知到和煦,but
本文走的吃吐少年路线,就不搞的那么高级了。

那就是说要如何轻松地落到实处丰富图片的反馈呢?我目前想到的是 ——
直接把标题图片发送到某些站点中去。

此间我们挑选微博的“日记”作用,它能够随意上传相关内容。

JavaScript

p.s.,其实那里原本是想一贯把图纸传遍天涯论坛相册上的,可惜POST请求的图纸实体须要走
file 格式,即不能够透过脚本改动文件的 input[type=file],转 Blob
再上传也没用,只可以作罢。

1
p.s.,其实这里原本是想直接把图片传到博客园相册上的,可惜POST请求的图片实体要求走 file 格式,即无法通过脚本更改文件的 input[type=file],转 Blob 再上传也没用,只好作罢。

咱俩在治本后台创造日记时,通过 Fiddler 抓包能够见到其请求参数万分轻便:

金沙注册送58 8

故此得以从来协会贰个请求:

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,通过 
的地方访问页面,开采摄像头竟然失效了~

通过谷歌(Google)的文书档案能够摸清,那是为着安全性考虑,非
HTTPS 的服务端请求都不可能联网录像头。但是解决办法也是1对,以 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
中得重复登入果壳网。

此时便能健康访问录制头了,我们对代码做下处理,当差别检验发掘至极时,创造1份日记,最小间隔时间为5秒(不过后来意识没需要,因为今日头条已经有做了光阴限定,差不多10秒后才具揭穿新的日记)

JavaScript

//定时捕获 function timer(delta){ setTimeout(function(){
captureAndSaveFrame(); renderDiff(); if(calcDiff() > 0.二){
//监察和控制到11分,发日志 submit() } timer(delta) }, delta || 500); }
setTimeout(timer, 四千0 * 十); //设定张开页面拾分钟后才起来监控//至极图片上传管理 function submit(){ var cache = arguments.callee, now
= Date.now(); if(cache.req提姆e && (now – cache.reqTime < 5000))
return; //日记创立最小间隔为5秒 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)
            }
        });
    }

施行职能:

金沙注册送58 9

日记也是妥妥的出来了:

金沙注册送58 10

点开就能看出那二个的那张图纸了:

金沙注册送58 11

要留意的是,微博对日记发表数量是有做每天额度限制来防刷的,到达限额的话会招致当天的随笔和小说也无力回天揭橥,所以得小心选择:

金沙注册送58 12

不过这种样式仅能申报卓殊图片,暂且无法让大家立即收悉告警,有意思味的童鞋能够试着再写个
chrome 插件,按时去拉取日记列表做推断,假若有新扩充日记则触发页面 alert。

其余我们自然期待能直接对闯入者实行警示,那块相比好办 ——
搞个警示的节拍,在老大的时候接触播放即可:

JavaScript

//播放音频 function fireAlarm(){ audio.play() } //定时捕获 function
timer(delta){ set提姆eout(function(){ captureAndSaveFrame(); if(preFrame
&& curFrame){ renderDiff(); if(calcDiff() > 0.二){ //监控到13分//发日记 submit(); //播放音频告警 fireAlarm(); } } timer(delta) }, delta
|| 500); } setTimeout(timer, 五千0 * 十);
//设定展开页面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
评论

金沙注册送58 13

原理

大家领会,通过为静态财富设置Cache-ControlExpires响应头,能够迫使浏览器对其开始展览缓存。浏览器在向后台发起呼吁的时候,会先在本人的缓存里面找,倘诺缓存里面未有,才会三番五次向服务器请求这些静态财富。利用那一点,大家得以把一些索要被缓存的音信透过那个静态能源缓存机制来开始展览仓储。

这就是说大家怎么把新闻写入到静态财富中吗?canvas提供了.getImageData()方法和.createImageData()方法,能够分别用于读取设置图片的rgba值。所以我们能够动用这八个API进行音讯的读写操作。

接下去看规律图:

金沙注册送58 14

当静态能源进入缓存,以往的别的对于该图片的乞请都会先找找当地缓存,也正是说新闻实际早就以图表的款式被缓存到地面了。

注意,由于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(888八);// 终端打字与印刷如下音讯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’)

其1静态能源的功效很简短,它提供了多少个职能:通过客户端传来的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设置宽度为八,高度为壹。到底为何三十二人数据对应长度为八,是因为每三个像素都有3个rgba,对应着redgreenbluealpha5个数值,所以须要除以4。

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, 8, 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

结果分析

张开服务器,运转客户端,第三次加载的时候经过调整台能够看来响应的图片音信:

金沙注册送58 15

200 OK,注脚是从服务端获取的图片。

关门当前页面,重新载入:

金沙注册送58 16

200 OK (from cache),声明是从本地缓存读取的图纸。

接下去直接看rgba值的对峙统1:

源数据: [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值给定为25伍而从不把循环赋值的逻辑进行翻新,所以第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);

后记

正是说黑科学和技术,其实原理非常轻易,与之类似的还有通过Etag等措施开始展览强缓存。钻探的目的无非为了学习,千万不要看成地下之用。假诺读者们开采那篇文章有啥样错漏之处,接待指正,也愿意有意思味的情人可以一并进行座谈。

多谢您的翻阅。作者是Jrain,接待关切本身的专栏,将不定时分享自个儿的就学经验,开拓心得,搬运墙外的干货。下次见啦!

1 赞 2 收藏 1
评论

金沙注册送58 17

* 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,8,”utf八”);//数据,起首下标,能存多少位,编码方式

const url = require(‘url’);

console.log(“写入字节数 : “+ len);//八
存入哥们并且打字与印刷出来:
var buf = new Buffer(‘你好本人是数据’);

const fs = require(‘fs’);

console.log(buf.toString());
合并buffer:
var buffer一 = new Buffer(‘新手教程 ‘);var buffer2 = new
Buffer(‘www.runoob.com’);var;var)
buffer3 = Buffer.concat([buffer1,buffer2]);console.log(“buffer3 内容:
” + buffer3.toString());

//创立四个劳动

Node.js Stream(流)
http 服务器发起呼吁的request 对象正是1个 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’});

// 创设叁个可读流
var readerStream = fs.createReadStream(‘message.txt’);

res.write(‘my nodejs’);

// 创设三个可写流
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(“文件解压完结。”);

//监听1个端口

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

3.赢得UPAJEROL部分块的剧情 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 是2个全局变量,即 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”
是一个不当对象回来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 UENCOREL编码的多寡
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(‘进入了另一个路线’);
})
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);

  1. 1体化实例(依照分裂的url地址请求例外的公文【模板】)

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);

//注册多少个事件处理的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;

}

});

相关文章

网站地图xml地图