简易静态服务器

最基本的静态文件服务器

nodejs中Stream是EventEmitter的实现,你可以理解为在程序后台打开了一个文件(不占用主线程), 程序会一点一点的读取(写入)文件,通过事件和回调来完成文件的读写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var http = require('http')
var parse = require('url').parse
var fs = require('fs')
var join = require('path').join

var root = __dirname
var server = http.createServer(function(req, res){
var url = parse(req.url)
var path = join(root, url.pathname)
var stream = fs.createStream(path)
stream.on('data',function(chunk){
res.write(chunk)
})
stream.on('end',function(){
res.end()
})
})

server.listen(3000)

处理服务器错误,保证运行不中断

在node中所有继承EventEmitter的类都可能会发出error的事件,fs.ReadStream这样的流是专用的EventEmitter,会有定义好的data和end事件,但是并没有处理error的事件,如果不监听这些错误,就会搞垮服务器。

1
2
3
4
5
// 所以在fs.ReadStream注册一个error事件处理器
stream.on('error',function(err){
res.statusCode = 500
res.end('Internet Server Error')
})

检查文件是否存在,并在响应中提供Content-Length

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
var server = http.createServer((req,res)=>{
var parse = require('url').parse
var join = require('path').join
var path = join(__dirname,parse(req.url).pathname)

fs.stat(path,(err,stat)=>{
if(err){
if('ENOENT' == err.code){
res.status = 404
res.end('file not found')
}else{
res.status = 500
res.end('Internet Server error')
}
}else{
res.setHeader('Content-Length',stat.size)
var stream = fs.createReadStream(stat)
stream.pipe(res)
stream.on('error',(err)=>{
res.statusCode = 500;
res.end('Internet server error')
})
}
})
})

content-length可以让浏览器判断什么时候数据接收已经完成。谷歌浏览器在打开网页的时候,有时候页面的icon一直在转圈,就是因为数据没有接收完毕,一直在等待数据。