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. 安卓 内存 泄漏 工具 LeakCanary 使用

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com LeakCanary是Square开源了一个内存泄露自动探测神器 .这是项目的github仓库地 ...

  2. 【动态规划】Round Subset

    CF837D. Round Subset Let's call the roundness of the number the number of zeros to which it ends. Yo ...

  3. 【POJ】1088滑雪

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 97335   Accepted: 36911 Description ...

  4. 【带权并查集】【离散化】vijos P1112 小胖的奇偶

    每个区间拆成r和l-1两个端点,若之内有偶数个1,则这两个端点对应的前缀的奇偶性必须相同,否则必须相反. 于是可以用带权并查集维护,每个结点储存其与其父节点的奇偶性是否相同,并且在路径压缩以及Unio ...

  5. Java学习笔记(7)

    构造函数: 构造函数的作用:给对应的对象进行初始化. 构造函数定义的格式: 修饰符   函数名(形式参数){ 函数体... } 构造函数要注意的细节: 构造函数是没有返回值类型的 构造函数的函数名必须 ...

  6. Java源代码编译过程

      编译其本质是将一种语言规范转换成另一种语言规范,即将Java语言规范转换为JVM虚拟机语言规范.结果就是.java文件到.class文件. 对于C/C++编译直接将高级语言转换为机器语言,Java ...

  7. 94.Txx考试

    2894 Txx考试  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description Txx是一个成绩很差的人,考试便成了他 ...

  8. node.js创建并引用模块

    app.js var express = require('express'); var app = express(); var con = require('./content'); con.he ...

  9. JS的数组相关知识

    创建数组方法一: var a1=new Array(5); console.log(a1.length); console.log(a1); //[] ,数组是空的 var a2=new Array( ...

  10. WINXP上安装及使用SqlMap之方法

    1.首先下载SqlMap 点击下载.2.其次下载用于Windows系统的Python ……点击这里…… 3.然后安装Python:Python默认安装的路径是“C:\Python”(你也可以修改安装路 ...