Node.js开发入门(1)我们用http模块实现了一个简单的HelloWorld站点,这次我们再来细致分析下代码。了解很多其它的细节。

先看看http版本号的HelloWorld代码:

代码就是这么简单:

// 引入http模块
var http = require("http"); // 创建server,指定处理client请求的函数
http.createServer(
function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World!");
response.end();
}
).listen(8000); console.log("Hello World is listening at port 8000");

HelloWorld代码分析

好啦,从如今開始逐行分析我们的HelloWorld。

引入模块

var http = require("http");

require方法用来引入一个模块,參数是模块的名字。比方File System模块。能够这么引入:

var fs = require("fs");

我们能够把require()方法当做全局方法使用。但实际上它更像属于某个模块的本地方法,它的文档參考这里:https://nodejs.org/api/globals.html

require方法返回某个模块的实例,比方require(“http”)就返回一个HTTP实例。HTTP实例的參考文档在这里:https://nodejs.org/api/http.html

我们看到。HTTP模块有一个方法createServer(),就牵涉到我们的第二行代码了。

创建server

HTTP模块的createServer()方法,接受一个方法作为參数,原型为:

http.createServer([requestListener])

requestListener是一个方法,会与http.Server类的request事件关联起来。这样当client请求到达时,requestListener就会被调用。

requestListener有两个參数,函数原型例如以下:

function (request, response) { }

第一个參数request的类型是http.IncomingMessage,实现了Readable Stream接口。第二个參数的类型是http.ServerResponse,实现了Writeable Stream接口。Stream的API在这里:https://nodejs.org/api/stream.html

同一时候,request和response还是EventEmitter。能够发射特定的事件。EventEmitter的API在这里:https://nodejs.org/api/events.html#events_class_events_eventemitter,后面我们会讲怎样使用EventEmitter来发射事件、处理事件。

再回想一下我们创建server的代码:

http.createServer(
function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World!");
response.end();
}
).listen(8000);

http.createServer返回一个http.Server实例。http.Server的listen方法能够让server监听在某个端口上。演示样例中是8000。

如你所见,我们提供了一个匿名函数给createServer方法。在这种方法中。我们通过response參数向client回写了“Hello World!”消息。

分析client请求

前面我们分析了http.createServer方法,它的參数是一个带两个參数的方法,一个代表了client发过来的请求。一个代表了要回写给client的响应。

我们来看看request參数。

request是http.IncomingMessage的实例,通过这个实例,我们能够拿到请求參数。比方HTTP方法、HTTP版本号、url、头部等。详细的API在这里:https://nodejs.org/api/http.html#http_http_incomingmessage

我们通过改动HelloWorld.js来看看(另存为HelloWorld2.js)。代码例如以下:

// 引入http模块
var http = require("http"); // 创建server,指定处理client请求的函数
http.createServer(
function(request, response) {
console.log("method - " + request.method);
console.log("version - " + request.httpVersion);
console.log("url - " + request.url);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World!");
response.end();
}
).listen(8000); console.log("Hello World start listen on port 8000");

如你所见,我使用console这个对象来输出了一些调试信息。打印了HTTP方法、版本号、url等信息。能够运行node HelloWorld2.js,浏览器訪问http://localhost:8000。然后跑到命令行看看输出了什么信息,我这里是这种:

发送响应给client

我们简简单单的HelloWorld已经能够发送一些响应数据给client,你在浏览器里能看到“Hello World!”字样。

这个响应是通过http.ServerResponse的实例response发送给client的。

http.ServerResponse也是一个Stream。还是一个EventEmitter。我们通过它给客户度返回HTTP状态码、数据、HTTP头部等信息。

解释一些基本概念。

HTTP响应由状态行+头部+数据组成。基本结构例如以下:

|——————————————————|

|HTTP version|status code|message|

|—————————————————–|

| HEADER-NAME-1: value |

|—————————————————–|

|HEADER-NAME-2: value |

|—————————————————–|

|HEADER-NAME-2: value |

|—————————————————–|

|空行(CRLF) |

|—————————————————–|

|可选数据(body) |

|—————————————————–|

HTTP状态码

就是200、301、302、403、404之类的数字,由server告诉client这次请求的状态,是成功了呢,还是找不到文件,还是……详细看这里http://kb.cnblogs.com/page/130970/

在Node.js的HTTP模块,状态行就是通过http.ServerResponse的writeHead方法写给client的。writeHead方法原型例如以下:

response.writeHead(statusCode[, statusMessage][, headers])

这种方法的第一个參数,就是statusCode,也就是200、403之类的数字,剩下的參数是可选的。最后一个參数是headers,你能够在这里使用JSON对象表示法来写一些HTTP头部,比方:{“Content-Type”:”text/plain”,”Content-Length”:11}。第一个可选參数statusMessage用来指定一个状态描写叙述消息。能够不填写。

HTTP头部

头部就是一些key-value对。比方我们在HelloWorld里看到的”Content-Type”,就是用来说明数据类型的头部标签,相应的可能是文本文件、图片、视频、二进制等。

相似的还有”Content-Length”,用来指定数据长度。

还有非常多非常多,比方”Date”、”Connection”等。

详细还是參考前面的链接吧。

头部还能够使用http.ServerResponse的response.setHeader(name, value)方法来单独设置,一次能够设置一个HTTP头部。

数据

头部之后就是数据了。有些状态码,比方200,兴许都会有一些数据。而有些,比方301、404、403、500之类的。多数没有数据。

数据通过http.ServerResponse的write方法来写回给client,比方这样:

response.setHeader("Content-Type", "text/html");

这里要提一点,HTTP常见的数据传输编码方式有两种:

  • 设置Content-Length,传输固定长度的数据
  • 设置Transfer-Encoding头部为chunked,分块数据传输

像我们如今的HelloWorld演示样例,没有设置Content-Length头部。Node.js的HTTP模块就默觉得chunked编码。

我们使用Chrome浏览器的开发人员工具来查看网络数据。能够非常明白的看到。

例如以下图所看到的:

我标注出来的三处,都是HelloWorld演示样例传递给浏览器的HTTP头部信息。

我们通过http.ServerResponse的write方法向client写数据。

你能够一次写入全部数据。也能够把数据分开来多次写入。

当要传输的数据量较大时。分多次写入就是比較合理的做法,比方你向client发送大文件。就比較适合分多次写入。也能够利用Node.js的异步特性,获得不错的性能。


好啦,这次我们略微详细地分析了一遍HelloWorld,下次呢。我们实现一个简单的文件server,会使用到很多其它的Node.js模块和API。

Node.js开发入门—HelloWorld再分析的更多相关文章

  1. Node.js开发入门—使用cookie保持登录

    这次来做一个站点登录的小样例,后面会用到. 这个演示样例会用到Cookie.HTML表单.POST数据体(body)解析. 第一个版本号,我们的用户数据就写死在js文件中. 第二个版本号会引入Mong ...

  2. Node.js开发入门—使用AngularJS

    做一个Web应用,一般都有前台和后台,Node.js能够实现后台.利用jade模板引擎也能够生成一些简单的前台页面,但要想开发出具有实际意义的现代Web应用.还得搭配一个Web前端框架. Angula ...

  3. Node.js开发入门—套接字(socket)编程

    Node.js的net模块提供了socket编程接口,方便我们利用较为底层的套接字接口来实现应用协议.这次我们看一个简单的回显服务器示例,包括服务端和客户端的代码. 代码 分服务器和客户端两部分来说吧 ...

  4. node.js开发学习一HelloWorld

    前言:由于公司业务需求,最近启动了node.js的开发任务,想把自己的开发学习历程记录记录下来,可以增加记忆,也方便查找.虽然对javascript有一定的了解,但是刚接触node.js的时候,发现还 ...

  5. Node.js快速入门

    Node.js是什么? Node.js是建立在谷歌Chrome的JavaScript引擎(V8引擎)的Web应用程序框架. 它的最新版本是:v0.12.7(在编写本教程时的版本).Node.js在官方 ...

  6. 《Node.js开发指南》知识整理

    Node.js简介 Node是一个可以让JavaScript运行在服务器端的平台,抛弃了传统平台依靠多线程来实现高并发的设计思路,而采用单线程.异步式I/O.事件驱动式的程序设计模型. 安装和配置No ...

  7. heX——基于 HTML5 和 Node.JS 开发桌面应用

    heX 是网易有道团队的一个开源项目,允许你采用前端技术(HTML,CSS,JavaScript)开发桌面应用软件的跨平台解决方案.heX 是你开发桌面应用的一种新的选择,意在解决传统桌面应用开发中繁 ...

  8. 学习Nodejs:《Node.js开发指南》微博项目express2迁移至express4过程中填的坑

    <Node.js开发指南>项目地址https://github.com/BYVoid/microblog好不容易找到的基础版教程,但书中是基于express2的,而现在用的是express ...

  9. Node.js核心入门

    前言: 因为以前学习Node.js并没有真正意义上的去学习它,而是粗略的学习了npm的常用命令和Node.js一些模块化的语法,因此昨天花了一天的时间看了<Node.js开发指南>一书.通 ...

随机推荐

  1. POJ2068 Nim 博弈论 dp

    http://poj.org/problem?id=2068 博弈论的动态规划,依然是根据必胜点和必输点的定义,才明白过来博弈论的dp和sg函数差不多完全是两个概念(前者包含后者),sg函数只是mex ...

  2. BZOJ 3289 Mato的文件管理(莫队+树状数组)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3289 [题目大意] 求静态区间逆序对. [题解] 我们对查询进行莫队操作,对于区间的删 ...

  3. 【贪心】【堆】bzoj2590 [Usaco2012 Feb]Cow Coupons

    每个物品有属性a,b 考虑在仅仅用光优惠券时的最优方案. 显然是按照b排序,取前K个. 但是我们还要尽可能去取剩余的. 假设朴素地取剩余的话,应该把剩余的对a排序,然后尽量去取. 但是有可能对其用优惠 ...

  4. 【强联通分量缩点】【Tarjan】bzoj1051 [HAOI2006]受欢迎的牛

    就是看是否有一些点,从其他任何点出发都可到达 定理:有向无环图中唯一出度为0的点,一定可以由任何点出发均可达. 所以缩点,若出度为零的点(强联通分量)唯一,则答案为该强联通分量中点的度数. 若不唯一, ...

  5. Linux 的硬链接与软链接

    Linux 的硬链接与软链接    http://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/    若一个 inode 号对 ...

  6. 在XC2440的uboot中挂载U盘,利用FAT文件系统读写U盘文件

    转:http://blog.chinaunix.net/uid-22030783-id-3347608.html 在XC2440的uboot_V1.3版本中已经支持USB HOST驱动和FAT文件系统 ...

  7. 通过pl/sql计算程序的运行时间

    在sqlplus中运行sql语句或者pl/sql的时候如果需要统计运行的时间,只需要开启set timing on选项即可. SQL> set timing onSQL>SQL> s ...

  8. AS3.0纯代码编写的两款loading效果

    AS3.0纯代码编写的两款loading效果 效果一 效果二 代码很简单,实现的原理一样,只不过矩形用到了Matrix类,对注册点进行了调整,效果可用于视频播放器缓冲时的loading效果,下面看代码 ...

  9. Netty游戏服务器之四protobuf编解码和黏包处理

    我们还没讲客户端怎么向服务器发送消息,服务器怎么接受消息. 在讲这个之前我们先要了解一点就是tcp底层存在粘包和拆包的机制,所以我们在进行消息传递的时候要考虑这个问题. 看了netty权威这里处理的办 ...

  10. 二十四种设计模式:访问者模式(Visitor Pattern)

    访问者模式(Visitor Pattern) 介绍表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 示例有一个Message实体类,某些对象对 ...