- 目录
{:toc #meuid}
0.前言
NodeJS是什么?
JavaScript是一种运行在浏览器的脚本,它简单,轻巧,易于编辑,这种脚本通常用于浏览器的前端编程,但是一位开发者Ryan有一天发现这种前端式的脚本语言可以运行在服务器上的时候,一场席卷全球的风暴就开始了。
Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行的数据密集型的实时应用。

Node是一个Javascript运行环境(runtime)。实际上它是对Google V8引擎进行了封装。V8引 擎执行Javascript的速度非常快,性能非常好。Node对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好。
我们该如何入门学习?
对于一个新的技术来说,入门学习很重要,如果有一个好的入门学习资料,将会对以后深入学习该技术产生很大的帮助,本文就是以这中思想来解说的,希望能够对学习NodeJS的人来说有一个好的开始,也欢迎大家对本文指出不足。
关于如何安装NodeJS,对于Linux上用户直接到官网下载编译过的安装包,然后加入到环境变量中即可
ln -s /home/software/node-v0.12.7-linux-x64/bin/node /usr/local/bin/node
ln -s /home/software/node-v0.12.7-linux-x64/bin/npm /usr/local/bin/npm
输入node回车即可进入node命令。
1.了解结构
入口:
var server=require("./server");
server.start();
NodeJS入口是指node命令后面要执行的文件,例如”node helloworld.js”即可之执行编写的代码,其中require是之加载模块,这里加载了本地的一个模块,也可加载内置的模块,比如require(“http”),是指加载node中自带的http模块,这点和函数式编程有点像。后面就可以调用具体的function了,这点就是Javascript里面的东西了,很简单吧。
server:
function start(){
function onRequest(request,response){
router.route(pathname,request,response,null);
}
http.createServer(onRequest).listen(8888);
}
exports.start=start;
server.js中的内容就是服务请求的入口了,包含请求的处理,路由的处理。最好是把处理放在一个单独的文件中这样管理起来也很方便。exports就是把该方法暴露出去,可以让外边的程序调用。最后在一个端口上监听就可以了.
route:
function route(pathname,request,response,data){
handler.menu(request,response,data);
}
exports.route=route;
对于路由后的内容要有一个处理的文件,就是requestHandlers,这个文件中是对每个路由到的地址进行具体的请求。
handler:
function menu(request,response,postdata){}
function start(request,response,postdata){}
function textpost(request,response,postdata){}
function filepost(request,response,postdata){}
exports.menu=menu;
exports.start=start;
exports.textpost=textpost;
exports.filepost=filepost;
每个对应一个请求,这是一种最简单的处理方式。
了解以上的内容后,就可以写一个简单的有结构的程序了,下面的示例是在以上的基础上演示了几种常见的情景:非阻塞请求,post数据,查看图片,上传图片。
2.示例一:阻塞演示
对于处理一个比较费时的操作,如果要在当前线程中处理的话会阻塞,一旦产生阻塞就会影响其它请求的执行,一种处理阻塞的方法时利用回调,将好事耗时的任务利用child_process的操作来执行,也可以将response的方法在数据处理完后发送给客户端。
在requestHandlers.js中start的方法演示了如何处理阻塞请求:
function start(request,response,postdata){
console.log("request handler 'start' was called.");
exec("find /",{timeout:10000,maxBuffer:20000*1024},function(error,stdout,stderr){
response.writeHead(200,{"Content-Type":"text/plain"});
response.write(stdout);
response.end();
});
}
3.示例二:post请求
对于一个请求,如果不带参数的化可以直接路由即可,但对于post方法中带的数据的情况,node 中有专门的方法处理,由于该过程也回产生阻塞,为了使整个过程非阻塞,Node.js会将POST数据拆分成很多小的数据块,然后通过触发特定的事件,将这些小数据块传递给回调函数。这里的特定的事件有data事件(表示新的小数据块到达了)以及end事件(表示所有的数据都已经接收完毕)。
我们需要告诉Node.js当这些事件触发的时候,回调哪些函数。怎么告诉呢? 我们通过在request对象上注册监听器(listener) 来实现。这里的request对象是每次接收到HTTP请求时候,都会把该对象传递给onRequest回调函数。
在server.js中onRequest的方法演示了如何该情况:
request.setEncoding("utf-8");
request.addListener("data",function(postDataChunk){
postData+=postDataChunk;
console.log("Received POST data:"+postDataChunk+".");
});
request.addListener("end",function(){
router.route(pathname,request,response,postData);
});
requestHandlers.js中upload方法就可以拿到数据,然后写回客户端:
response.writeHead(200,{"Content-Type":"text/plain"});
response.write("You've sent : "+querystring.parse(postdata).text);
response.end();
4.示例三:查看图片
对于查看服务器上的资源,可以用file system模块,调用方式如:require(“fs”).
requestHandlers.js中show方法就是读取一个图片的示例:
fs.readFile("/root/图片/new.png","binary",function(error,file){
if(error){
response.writeHead(500,{"Content-Type":"text/plain"});
response.write(error+"\n");
response.end();
}else{
response.writeHead(200,{"Content-Type":"image/png"});
response.write(file,"binary");
response.end();
}
});
在示例中不仅此处用了该方法,加载具体的html文件也用到该模块。
5.示例四:图片上传
文件上传也是一个比较常见的情形,单要用到一个模块formidable,该模块需要自己安装,node默认没有自带.
安装方法:
npm install formidable
requestHandlers.js中uploadfile方法就是处理上传上来的文件的示例:
var form=new formidable.IncomingForm();
form.parse(request,function(error,fields,files){
fs.renameSync(files.upload.path,"/root/图片/new.png");
response.writeHead(200,{"Content-Type":"text/html"});
response.write("received image:<br/>");
response.write("<img src='/show' />");
response.end();
});
注意的是:这里不再调用addListener方法,而是要自己处理上传的资源。
单独的处理,避免和其它处理方式混淆:
if(pathname=="/uploadfile"){
router.route(pathname,request,response,null);
}else{
//.....
}
6.总结
通过这几个示例可以更加深入的了解到node的开发方式,希望能对刚入门的人有一个指导性的作用。