一个相对健壮的node 静态http服务器
先上代码,然后说说坑,算是一个总结,以后在mac上就用这个开启服务调试了,挺好。然后接着想写一个动态的返回页面的,刚好练手mv*的框架。
1 var http = require('http'); 2 var fs = require('fs'); 3 var url = require('url'); 4 var filedir = []; 5 fs.readdir('www',function(err,file){ 6 console.log('readdir'); 7 lengthlast = file.length;//initzien lengthlast 8 console.log('lengthlast:'+lengthlast); 9 if (err) { 10 throw('you have no "www" dir'); 11 }; 12 for(var n=0;n<file.length;n++){ 13 filedir[n]=file[n]; 14 } 15 16 fs.watch('www',function(event,filename){//observe dir.if dir is not changed,it doesn't work; someting error 17 if (filename!== '.DS_Store') { 18 print(filename+'changed'); 19 fs.readdir('www', function(err,file){ 20 if (err) { 21 ; 22 }; 23 if (file.length>lengthlast) {//append file 24 25 filedir.push(filename); 26 lengthlast = file.length; 27 console.log('append:'+lengthlast); 28 } 29 else{ 30 31 for(var j = 0;j<filedir.length;j++){ 32 if (filedir[j]==filename) { 33 filedir.splice(j,1); 34 lengthlast = file.length; 35 console.log('remove:'+lengthlast); 36 }; 37 } 38 print(file); 39 } 40 }) 41 } 42 43 }); 44 45 http.createServer(function(req,res){ 46 var length = filedir.length; 47 console.log('connact server'); 48 var urlobj = url.parse(req.url); 49 if(urlobj&&urlobj.path!=='/favicon.ico'){ 50 var filepath = urlobj.path; 51 } 52 53 54 if (filepath == undefined) { 55 56 res.writeHead(200,{ 57 'Content-Type':'text/html' 58 }); 59 res.end('404 NOT FOUND'); 60 return; 61 }; 62 63 function removefirst(str){ 64 var string = str; 65 var arr = string.split(''); 66 arr.shift(); 67 return arr.join(''); 68 } 69 var reqfile=removefirst(filepath); 70 71 72 for(var i=0;i<length;i++){//loop 2 ? why 73 74 if ('/'+filedir[i]==filepath) { 75 76 var data = fs.readFileSync('www'+filepath);//这里异步有问题,你异步去读文件,但是循环继续了,很快完成,报not found 文件来了已经over 77 78 res.writeHead(200,{ 79 'Content-Type':'text/html' 80 }); 81 if (!data) { 82 res.end('something erro'); 83 }; 84 85 res.write(data,'bindary'); 86 res.end(); 87 break; 88 }; 89 if (i==(length-1)) { 90 91 res.end('404 NOT FOUND'); 92 }; 93 } 94 95 96 }).listen(8080,'127.0.0.1'); 97 98 99 100 101 }); 102 console.log("server start"); 103 104 function print(something){ 105 console.log(something); 106 }
第一个是不要用foreach去遍历数组,这是对象的方法,尽管可以用来遍历数组但是经常会冒出来一些奇怪的东西,使用有风险。
第二个就是node返回文件的要注意你是以什么格式返回的
第三个就是异步的问题,异步的写法不是那么好写的,要时刻注意变量的值的改动和异步执行的逻辑流。
说一下程序的大体思路,
最简单的返回文件的http服务器有一个问题就是,如果请求一个并不存在的文件,服务器就会挂掉,这个简单,我们做一个过滤就好了,当请求一个并不存在的文件的时候返回404即可,所以就要维护一个文件dir的对象或者数组,我用的数组,感觉用对象还是有一些便利的,或者也可以使用类数组。然而,我们并不能把数组或者对象写死,因为服务器www目录下的文件不是一成不变的,所以我们要去readdir,然而每来一次请求就readdir很麻烦,效率也低,所以我们就watchdir的变动,这边有一个要注意的地方就是我们要知道它是append还是remove文件这个要自己写一下,所以,这样一旦www目录下有changed事件就去upadate数组,然后就可以防范请求不存在的文件而使得服务器挂掉的情况。