博文共赏:Node.js静态文件服务器实战
【编者按】《博文共赏》是InfoQ中文站新推出的一个专栏,精选来自国内外技术社区和个人博客上的技术文章,让更多的读者朋友受益,本栏目转载的内容都经过原作者授权。文章推荐可以发送邮件到[email protected]。
\本文是我对V5Node项目的总结,该项目的特性包括:
\- 项目大多数的文件都是属于静态文件,只有数据部分存在动态请求。\
- 数据部分的请求都呈现为RESTful的特性。\
所以项目主要包含两个部分就是静态服务器和RESTful服务器。本文讲的是静态文件服务器部分。
\既是一个新的项目,那么创建v5node目录是应该的。既是一个Node应用,创建一个app.js文件也是应该的。
\我们的app.js文件里的结构很明确:
\\var PORT = 8000;\var http = require('http');\var server = http.createServer(function (request, response) {\ // TODO\});\server.listen(PORT);\console.log(\"Server runing at port: \" + PORT + \".\");\\
因为当前要实现的功能是静态文件服务器,那么以Apache为例,让我们回忆一下静态文件服务器都有哪些功能。
\浏览器发送URL,服务端解析URL,对应到硬盘上的文件。如果文件存在,返回200状态码,并发送文件到浏览器端;如果文件不存在,返回404状态码,发送一个404的文件到浏览器端。
\以下两图是Apache经典的两种状态。
\现在需求已经明了,那么我们开始实现吧。
\实现路由
\路由部分的实现在《The Node Beginner Book》已经被描述过,此处不例外。
\添加url模块是必要的,然后解析pathname。
\以下是实现代码:
\\var server = http.createServer(function (request, response) {\ var pathname = url.parse(request.url).pathname;\ response.write(pathname);\ response.end();\});\
现在的代码是向浏览器端输出请求的路径,类似一个echo服务器。接下来我们为其添加输出对应文件的功能。
\读取静态文件
\为了不让用户在浏览器端通过请求/app.js查看到我们的代码,我们设定用户只能请求assets目录下的文件。服务器会将路径信息映射到assets目录。
\涉及到了文件读取的这部分,自然不能避开fs(file system)这个模块。同样,涉及到了路径处理,path模块也是需要的。
\我们通过path模块的path.exists方法来判断静态文件是否存在磁盘上。不存在我们直接响应给客户端404错误。
\如果文件存在则调用fs.readFile方法读取文件。如果发生错误,我们响应给客户端500错误,表明存在内部错误。正常状态下则发送读取到的文件给客户端,表明200状态。
\\var server = http.createServer(function (request, response) {\ var pathname = url.parse(request.url).pathname;\ var realPath = \"assets\" + pathname;\ path.exists(realPath, function (exists) {\ if (!exists) {\ response.writeHead(404, {\ 'Content-Type': 'text/plain'\ });\\ response.write(\"This request URL \" + pathname + \" was not found on this server.\");\ response.end();\ } else {\ fs.readFile(realPath, \"binary\