Node.JS基础知识

-- 运行在服务器端的javascript

Node.js API

 

一、创建HTTP Server

 

var http = require('http');

 

http.createServer(function (request, response) {

  response.writeHead(200,{'Content-Type': 'text/plain'});

  response.end('HelloWorld\n');

}).listen(8888);

 

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

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

 

二、模块系统

 

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。 

模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。

Node.js 提供了exports require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。

 

接下来我们就来创建hello.js文件,代码如下:

1

2

3

exports.world = function() {

  console.log('Hello World');

}

在以上示例中,hello.js 通过 exports 对象把 world 作为模块的访问接口,在 main.js 中通过require('./hello') 加载这个模块,然后就可以直接访 问main.js exports 对象的成员函数了。

如下我们创建一个 'main.js' 文件,代码如下:

1

2

var hello = require('./hello');

hello.world();

 

有时候我们只是想把一个对象封装到模块中,格式如下: 

1

2

3

module.exports = function() {

  // ...

}

例如

1

2

3

4

5

6

7

8

9

10

11

//hello.js 

functionHello() { 

    varname; 

    this.setName = function(thyName) { 

        name = thyName; 

    }; 

    this.sayHello = function() { 

        console.log('Hello ' + name); 

    }; 

}; 

module.exports = Hello;

这样就可以直接获得这个对象了:

1

2

3

4

5

//main.js 

varHello = require('./hello'); 

hello = new Hello(); 

hello.setName('BYVoid'); 

hello.sayHello(); 

 

 

三、事件

 

产生事件的对象都是events.EventEmitter 的实例。 你可以通过require("events");来访问该模块。

1

2

3

4

5

6

7

8

9

//event.js 

var EventEmitter = require('events').EventEmitter; 

var event = new EventEmitter(); 

event.on('some_event'function() { 

    console.log('some_event occured.'); 

}); 

setTimeout(function() { 

    event.emit('some_event'); 

}, 1000);

events 模块只提供了一个对象:events.EventEmitter。EventEmitter的核心就是事件发射与事件监听器功能的封装。

EventEmitter的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter支持若干个事件监听器。

 

其他EventEmitter常用API:

EventEmitter.on(event,listener)、emitter.addListener(event, listener)为指定事件注册一个监听器,接受一个字 符串event和一个回调函数listener。

EventEmitter.emit(event,[arg1], [arg2], [...])发射event事件,传递若干可选参数到事件监听器的参数表。

EventEmitter.once(event,listener)为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器。

EventEmitter.removeListener(event,listener) 移除指定事件的某个监听器,listener必须是该事件已经注册过的监听器。

EventEmitter.removeAllListeners([event])移除所有事件的所有监听器,如果指定event,则移除指定事件的所有监听器。

EventEmitter定义了一个特殊的事件 error,它包含了"错误"的语义,我们在遇到 异常的时候通常会发射 error 事件。

当 error被发射时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并打印调用栈。

 

 

四、函数

 

语法同javascript

1

2

3

4

5

6

7

8

9

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);

 

五、路由

 

我们要为路由提供请求的URL和其他需要的GET及POST参数,随后路由需要根据这些数据来执行相应的代码,我们需要额外的Node.JS模块,它们分别是url和querystring模块。

 

现在我们可以来编写路由了,建立一个名为router.js的文件,添加以下内容: 

1

2

3

4

5

function route(pathname) {

  console.log("About to route a request for " + pathname);

}

 

exports.route = route;

然后我们来给onRequest()函数加上一些逻辑,用来找出浏览器请求的URL路径,并将路由函数作为参数传递 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

var http = require("http");

var url = require("url");

 

function start(route) {

  function onRequest(request, response) {

    var pathname = url.parse(request.url).pathname;

    console.log("Request for " + pathname + " received.");

 

    route(pathname);

 

    response.writeHead(200, {"Content-Type": "text/plain"});

    response.write("Hello World");

    response.end();

  }

 

  http.createServer(onRequest).listen(8888);

  console.log("Server has started.");

}

 

exports.start = start;

同时,我们会相应扩展index.js,使得路由函数可以被注入到服务器中: 

varserver = require("./server"); var router =require("./router"); server.start(router.route); 

在这里,我们传递的函数依旧什么也没做。 

如果现在启动应用(node index.js,始终记得这个命令行),随后请求一个URL,你将会看到应用输出相应的信息,这表明我们的HTTP服务器已经在使用路由模块了,并会将请求的路径传递给路由: 

1

2

3

bash$ node index.js

Request for /foo received.

About to route a request for /foo

 

六、全局对象

 

Node.js中的全局对象是global,所有全局变量(除了global本身以外)都是global对象的属性。

我们在Node.js中能够直接访问到对象通常都是global的属性,如console、process等。

 

1process

 

process.argv是命令行参数数组,第一个元素是node,第二个元素是脚本文件名,从第三个元素开始每个元素是一个运行参数。

1

console.log(process.argv); 

 

process.stdout是标准输出流,通常我们使用的 console.log()向标准输出打印 字符,而 process.stdout.write() 函数提供了更底层的接口。

process.stdin是标准输入流,初始时它是被暂停的,要想从标准输入读取数据,你必须恢复流,并手动编写流的事件响应函数。

1

2

3

4

process.stdin.resume(); 

process.stdin.on('data'function(data) { 

process.stdout.write('read from console: ' + data.toString()); 

}); 

process.nextTick(callback)的功能是为事件循环设置一项任务,Node.js会在 下次事件循环调响应时调用 callback。

 

除此之外process还展示了process.platform、process.pid、process.execPath、process.memoryUsage()等方法,以及POSIX 进程信号响应机制。

详见http://nodejs.org/api/process.html

 

2console

 

console用于提供控制台标准输出,它是由InternetExplorer的JScript引擎提供的调试 工具,后来逐渐成为浏览器的事实标准。

console.log接受若干个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则以类似于C语言printf()命令的格式输出。

console.error():与console.log()用法相同,只是向标准错误流输出。

console.trace():向标准错误流输出当前的调用栈。

 

七、常用工具util

 

util是一个Node.js核心模块,提供常用函数的集合,用于弥补核心JavaScript的功能过于精简的不足。

 

util.inherits

util.inherits(constructor,superConstructor)是一个实现对象间原型继承的函数。

 

util.inspect

util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换为字符串的方法,通常用于调试和错误输出。它至少接受一个参数object,即要转换的对象。 

showHidden是一个可选参数,如果值为true,将会输出更多隐藏信息。

depth表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多 少。如果不指定depth,默认会递归2层,指定为null表示将不限递归层数完整遍历对象。如果color值为true,输出格式将会以ANSI颜色编码,通常用于在终端显示更漂亮的效果。

特别要指出的是,util.inspect并不会简单地直接把对象转换为字符串,即使该对 象定义了toString 方法也不会调用。

util.isArray(object)

如果给定的参数 "object"是一个数组返回true,否则返回false

util.isRegExp(object)

如果给定的参数 "object"是一个正则表达式返回true,否则返回false

util.isDate(object)

如果给定的参数 "object"是一个日期返回true,否则返回false

util.isError(object)

如果给定的参数 "object"是一个错误对象返回true,否则返回false

 

八、文件系统

 

Node.js文件系统封装在fs模块中

fs模块中所有的操作都提供了异步的和同步的两个版本,例如读取文件内容的函数有异步的 fs.readFile()和同步的fs.readFileSync()。

 

fs.readFile

1

fs.readFile(filename,[encoding],[callback(err,data)])

  • filename(必选),表示要读取的文件名。 
  • encoding(可选),表示文件的字符编码。 
  • callback 是回调函数,用于接收文件的内容。

如果不指 定 encoding,则callback 就是第二个参数。回调函数提供两个参数 err 和 data,err 表 示有没有错误发生,data 是文件内容。如果指定了encoding,data 是一个解析后的字符 串,否则 data 将会是以 Buffer 形式表示的二进制数据。

 

fs.open

fs.open(path, flags, [mode],[callback(err, fd)])POSIX open函数的封装,与C 语言标准库中的fopen函数类似。它接受两个必选参数,path为文件的路径,flags 可以是以下值。

  • r :以读取模式打开文件。
  • r+ :以读写模式打开文件。
  • w :以写入模式打开文件,如果文件不存在则创建。
  • w+ :以读写模式打开文件,如果文件不存在则创建。
  • a :以追加模式打开文件,如果文件不存在则创建。
  • a+ :以读取追加模式打开文件,如果文件不存在则创建

 

fs.read

1

fs.read(fd, buffer, offset, length, position, [callback(err, bytesRead, buffer)])

  • fd: 读取数据并写入 buffer 指向的缓冲区对象。
  • offset: buffer 的写入偏移量。
  • length: 是要从文件中读取的字节数。
  • position: 是文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
  • callback:回调函数传递bytesRead buffer,分别表示读取的字节数和缓冲区对象。

 

fs 模块函数表

nodejs-file1

 

nodejs-file2

 

 

九、GET/POST

 

1GET

 

node.js中url模块中的parse函数可用来解析GET请求的url

1

2

3

4

5

6

7

8

var http = require('http');

var url = require('url');

var util = require('util');

 

http.createServer(function(req, res){

    res.writeHead(200, {'Content-Type': 'text/plain'});

    res.end(util.inspect(url.parse(req.url, true)));

}).listen(3000);

 

2POST

 

node.js默认是不会解析请求体的,当你需要的时候,需要手动来做。 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

var http = require('http');

var querystring = require('querystring');

var util = require('util');

 

http.createServer(function(req, res){

    var post = '';     //定义了一个post变量,用于暂存请求体的信息

 

    req.on('data', function(chunk){    //通过reqdata事件监听函数,每当接受到请求体的数据,就累加到post变量中

        post += chunk;

    });

 

    req.on('end', function(){    //end事件触发后,通过querystring.parsepost解析为真正的POST请求格式,然后向客户端返回。

        post = querystring.parse(post);

        res.end(util.inspect(post));

    });

}).listen(3000);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值