β

Node.js入门教程(一)

ABCD数据库 3290 阅读
 什么是Node.js

Node.js 是服务器端的 JavaScript 运行环境,它允许在后端(脱离浏览器环境)运行JavaScript代码。Node.js具有无阻塞(non-blocking)和事件驱动(event-driven)等的特色,它实现了类似 Apache 和 nginx 的web服务,让你可以通过它来搭建基于 JavaScript 的 Web App。

要实现在后台运行JavaScript代码,代码需要先被解释然后正确的执行,Node.js的原理正是如此,它使用了Google的V8虚拟机(Google的Chrome浏览器使用的JavaScript执行环境),来解释和执行JavaScript代码。

除此之外,伴随着Node.js的还有许多有用的模块,它们可以简化很多重复的劳作,比如向终端输出字符串。 因此,Node.js事实上既是一个运行时环境,同时又是一个库。

关于如何安装Node.js,这里就不赘述,可以直接参考官方的安装指南。安装完成后,继续以下内容。

第一个Node.js应用:"Hello World"

打开编辑器创建一个helloworld.js文件,写入向STDOUT输出"Hello World"的代码:

console.log("Hello World");

保存该文件,并通过Node.js来执行:

node helloworld.js

终端将输出Hello World 。

一个基于Node.js的web应用实例的需求

· 用户可以通过浏览器使用我们的应用。
· 当用户请求http://domain/start时,可以看到一个欢迎页面,页面上有一个文件上传的表单。
· 用户可以选择一个图片并提交表单,随后文件将被上传到http://domain/upload,该页面完成上传后会把图片显示在页面上。

应用不同模块分析

· 我们需要提供Web页面,因此需要一个HTTP服务器
· 对于不同的请求,根据请求的URL,我们的服务器需要给予不同的响应,因此我们需要一个路由,用于把请求对应到请求处理程序(request handler)
· 当请求被服务器接收并通过路由传递之后,需要可以对其进行处理,因此我们需要最终的请求处理程序
· 路由还应该能处理POST数据,并且把数据封装成更友好的格式传递给请求处理入程序,因此需要请求数据处理功能
· 我们不仅仅要处理URL对应的请求,还要把内容显示出来,这意味着我们需要一些视图逻辑供请求处理程序使用,以便将内容发送给用户的浏览器
· 最后,用户需要上传图片,所以我们需要上传处理功能来处理这方面的细节

使用PHP的话一般来说会用一个Apache HTTP服务器并配上mod_php5模块。从这个角度看,整个"接收HTTP请求并提供Web页面"的需求根本不需要PHP来处理。

不过对Node.js来说,概念完全不一样了。使用Node.js时,我们不仅仅在实现一个应用,同时还实现了整个HTTP服务器。事实上,我们的Web应用以及对应的Web服务器基本上是一样的。似乎要做一大堆东西,但对Node.js来说这并不是什么麻烦的事。

首先从第一个部分——HTTP服务器着手:

构建应用的模块 一个基础的HTTP服务器

为了保持代码的可读性,把不同功能的代码放入不同的模块中,这样可以实现代码分离。这种方法允许你拥有一个干净的主文件(main file),你可以用Node.js执行它;同时你可以拥有干净的模块,它们可以被主文件和其他的模块调用。

现在我们来创建一个用于启动我们的应用的主文件,和一个保存着我们的HTTP服务器代码的模块。

先从服务器模块开始,在项目的根目录下创建一个叫server.js的文件,并写入以下代码:

var http = require("http");
http.createServer(function(request, response) {
   response.writeHead(200, {"Content-Type": "text/plain"});
   response.write("Hello World");
   response.end();
}).listen(8888);
/* 也可写成以下形式
var http = require("http");
function onRequest(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}
http.createServer(onRequest).listen(8888);
*/

这样就搭建了一个可以工作的HTTP服务端。为了证明这一点,我们来运行并且测试这段代码。首先,用Node.js执行你的脚本:

node server.js

接下来,打开浏览器访问http://localhost:8888/,你会看到一个写着"Hello World"的网页。

分析HTTP服务器

接下来分析一下这个HTTP服务器的构成。

第一行请求(require)Node.js自带的 http 模块,并且把它赋值给 http 变量。

接下来我们调用http模块提供的函数: createServer 。这个函数会返回一个对象,这个对象有一个叫做 listen 的方法,这个方法有一个数值参数,指定这个HTTP服务器监听的端口号。

本来可以用这样的代码来启动服务器并侦听8888端口:

var http = require("http");
var server = http.createServer();
server.listen(8888);

这段代码只会启动一个侦听8888端口的服务器,它不做任何别的事情,甚至连请求都不会应答。

基于事件驱动的回调

当使用 http.createServer 方法的时候,当然不只是想要一个侦听某个端口的服务器,我们还想要它在服务器收到一个HTTP请求的时候做点什么。

问题是,这是异步的:请求任何时候都可能到达,但是服务器却跑在一个单进程中。

写PHP应用的时候,我们一点也不为此担心:任何时候当有请求进入的时候,网页服务器(通常是Apache)就为这一请求新建一个进程,并且开始从头到尾执行相应的PHP脚本。那么在我们的Node.js程序中,当一个新的请求到达8888端口的时候,我们怎么控制流程呢?

这就是Node.js/JavaScript的事件驱动设计能够真正帮上忙的地方了——虽然我们还得学一些新概念才能掌握它。

先看看这些概念是怎么应用在我们的服务器代码里的:

我们创建了服务器,并且向创建它的方法传递了一个函数。无论何时我们的服务器收到一个请求,这个函数就会被调用。 我们不知道这件事情什么时候会发生,但是我们现在有了一个处理请求的地方:它就是我们传递过去的那个函数。至于它是被预先定义的函数还是匿名函数,就无关紧要了。这个就是回调 。我们给某个方法传递了一个函数,这个方法在有相应事件发生时调用这个函数来进行回调 。

让我们再来琢磨琢磨这个新概念。我们怎么证明,在创建完服务器之后,即使没有HTTP请求进来、我们的回调函数也没有被调用的情况下,我们的代码还继续有效呢?我们试试这个:

var http = require("http");
function onRequest(request, response) {
  console.log("Request received.");
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
注意:在 onRequest (我们的回调函数)触发的地方,我用 console.log 输出了一段文本。在HTTP服务器开始工作之后,也输出一段文本。

当我们与往常一样,运行它node server.js时,它会马上在命令行上输出"Server has started."。当我们向服务器发出请求(在浏览器访问http://localhost:8888/),"Request received."这条消息就会在命令行中出现。这就是事件驱动的异步服务器端JavaScript和它的回调。(请注意,当我们在服务器访问网页时,我们的服务器可能会输出两次"Request received."。那是因为大部分服务器都会在你访问 http://localhost:8888 /时尝试读取 http://localhost:8888/favicon.ico )

作者:ABCD数据库
www.abcd9.com - select,insert,update my data.
原文地址:Node.js入门教程(一), 感谢原作者分享。

评论

  • 可以参考 http://www.9958.pw/post/nodejs_lesson

    回复   |   摩羯、凌 发表于 2014-04-24 17:54:19

发表评论