配置NPM的环境变量: NODE_PATH:F: ode ode_modules //nodejs自带的NPM安装目录 ------------------------------------------------------------------------------------------- 用淘宝镜像来安装模块: $ npm install express -g --registry=http://registry.npm.taobao.org ------------------------------------------------------------------------------------------- Node.js REPL(Read Eval Print Loop:交互式解释器) 表示一个电脑的环境,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输入命令,并接收系统的响应。 简单的表达式运算 > x=20 20 > y=30 30 > x+y 50 使用变量 变量声明需要使用 var 关键字,如果没有使用 var 关键字变量会直接打印出来。 使用 var 关键字的变量可以使用 console.log() 来输出变量。 > var x=10 undefined > var y=20 undefined > console.log(x+y) 30 多行表达式 > var x=3 undefined > for(var i=0;i<x;i++){ ... console.log(i)} 0 1 2 下划线(_)变量 > x+y 23 > var m=_ undefined > console.log(m) 23 undefined C:Windowssystem32>node > url.parse('http://www.baidu.com'); url.parse('http://www.baidu.com'); Url { protocol: 'http:', slashes: true, auth: null, host: 'www.baidu.com', port: null, hostname: 'www.baidu.com', hash: null, search: null, query: null, pathname: '/', path: '/', href: 'http://www.baidu.com/' } > url; { parse: [Function: urlParse], resolve: [Function: urlResolve], resolveObject: [Function: urlResolveObject], format: [Function: urlFormat], Url: [Function: Url] } ------------------------------------------------------------------------------------------- Node.js 回调函数 Node.js 异步编程的直接体现就是回调。 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。 例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码 时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。 //阻塞代码实例 var fs=require('fs'); var text=fs.readFileSync('haha.txt','UTF-8'); console.log(text); //非阻塞代码实例 在 Node 应用程序中,执行异步操作的函数将回调函数作为最后一个参数, 回调函数接收错误对象作为第一个参数。 var fs=require('fs'); fs.readFile('haha1.txt','UTF-8',function(err,data){ if(err){ console.log(err.code) } console.log(data) }); ------------------------------------------------------------------------------------------- Node.js 事件循环 Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。 Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数. 事件驱动程序 Event模块(events.EventEmitter)的核心是事件发射与事件监听器。具有addListener/on,once,removeListener,removeAllListeners,emit等 基本的事件监听模式的方法实现。它与前端DOM树上的事件并不相同,因为它不存在冒泡,逐层捕获等属于DOM的事件行为,也没有preventDefault()、 stopPropagation()、 stopImmediatePropagation() 等处理事件传递的方法。 var events=require('events');// 引入 events 模块 var eventEmitter=new events.EventEmitter();//创建 eventEmitter 对象 eventEmitter.on('eventName', eventHandler);// 绑定事件及事件的处理程序 eventEmitter.emit('eventName'); //发射一个事件 function eventHandler(){ console.log('1111'); } eventEmitter.removeListener('eventName',eventHandler)//移除某事件监听,eventHandler不能为匿名的函数,否则移除不了指定事件的监听函数。 eventEmitter.removeAllListeners('eventName')//移除该事件的所有监听,不传参数的话就是移除全部事件的所有监听函数 var listenerEventsArr = eventEmitter.listeners('eventName');//返回值接收到event所有注册监听的集合. console.log(listenerEventsArr.length) var listenerCount=eventEmitter.listenerCount('eventName','eventHandler') //监听数 console.log(listenerCount) 如果对一个事件添加了超过10个侦听器,将会得到一条警告 emitter.setMaxListeners(0); //去掉限制,emitter.setMaxListeners的作用是给EventEmitter设置最大监听数 ------------------------------------------------------------------------------------------- error 事件 EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。 当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。 我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。 ------------------------------------------------------------------------------------------- Node.js Buffer(缓冲区) JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。 但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。 在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制 数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一 个整数数组,但它对应于 V8 堆内存之外的一块原始内存。 //创建长度为 10 字节的 Buffer 实例: var buf=new Buffer(100); //通过给定的数组创建 Buffer 实例: var buf = new Buffer([1,2,3,4,5]); //通过一个字符串来创建 Buffer 实例: var buf=new Buffer('www.baidu.com','UTF-8'); //写入缓冲区 /*buf.write(string[, offset][, length][, encoding]) 参数描述如下: string - 写入缓冲区的字符串。 offset - 缓冲区开始写入的索引值,默认为 0 。 length - 写入的字节数,默认为 buffer.length encoding - 使用的编码。默认为 'utf8' 。 返回值 返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串。*/ var ipt=buf.write('nihao'); console.log(ipt); /*从缓冲区读取数据 读取 Node 缓冲区数据的语法如下所示: buf.toString([encoding][, start][, end]) 参数描述如下: encoding - 使用的编码。默认为 'utf8' 。 start - 指定开始读取的索引位置,默认为 0。 end - 结束位置,默认为缓冲区的末尾。 返回值 解码缓冲区数据并使用指定的编码返回字符串。*/ var buf=new Buffer(20); buf.write('123456','utf-8') console.log(buf.toString('utf8',0,4));//小写编码没有横线 //将 Buffer 转换为 JSON 对象 var buffer2json=buf.toJSON(); console.log(buffer2json); //{ type: 'Buffer',data: [ 49, 50, 51, 52, 53, 54, 1, 0, 156, 166, 218, 0, 216, 168, 218, 0, 0, 0, 0, 0 ]} //缓冲区合并 /* Buffer.concat(list[, totalLength]) 参数描述如下: list - 用于合并的 Buffer 对象数组列表。 totalLength - 指定合并后Buffer对象的总长度。*/ var buf1=new Buffer('hello','UTF-8'); var buf2=new Buffer('world','UTF-8'); var buf3=new Buffer.concat([buf1,buf2]); console.log('buf3:'+buf3); /*缓冲区比较 buf.compare(otherBuffer); 参数描述如下: otherBuffer - 与 buf 对象比较的另外一个 Buffer 对象。 返回值 返回一个数字,表示 buf 在 otherBuffer 之前,之后或相同。*/ var buf1=new Buffer('hello','UTF-8'); var buf2=new Buffer('world','UTF-8'); var result=buf1.compare(buf2); if(result<0){ console.log(buf1 + " 在 " + buf2 + "之前"); }else if(result==0){ console.log(buf1 + " 在 " + buf2 + "相同"); }else{ console.log(buf1 + " 在 " + buf2 + "之后"); } /* 拷贝缓冲区 Node 缓冲区拷贝语法如下所示: buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd]) 参数 参数描述如下: targetBuffer - 要拷贝的 Buffer 对象。 targetStart - 数字, 可选, 默认: 0 sourceStart - 数字, 可选, 默认: 0 sourceEnd - 数字, 可选, 默认: buffer.length*/ var buf1=new Buffer('hello','UTF-8'); var buf2=new Buffer('world','UTF-8'); buf2.copy(buf1); console.log(buf2.toString('utf8'))//buf2会被覆盖 /*缓冲区裁剪 Node 缓冲区裁剪语法如下所示: buf.slice([start][, end]) 参数 参数描述如下: start - 数字, 可选, 默认: 0 end - 数字, 可选, 默认: buffer.length 返回值 返回一个新的缓冲区,它和旧缓冲区指向同一块内存,但是从索引 start 到 end 的位置剪切。*/ var buf1=new Buffer('hello','UTF-8'); var buf2=new Buffer('world','UTF-8'); var buf3=buf1.slice(0,1); console.log(buf3.toString()) console.log(buf3.length)//返回 Buffer 对象所占据的内存长度。 /*buf.fill(value[, offset][, end]) 使用指定的 value 来填充这个 buffer。如果没有指定 offset (默认是 0) 并且 end (默认是 buffer.length) ,将会填充整个buffer。*/ var buf=new Buffer(100); buf.fill('wokao'); console.log(buf.toString()); ------------------------------------------------------------------------------------------- Node.js Stream(流) Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。 Node.js,Stream 有四种流类型: Readable - 可读操作。 Writable - 可写操作。 Duplex - 可读可写操作. Transform - 操作被写入数据,然后读出结果。 所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有: data - 当有数据可读时触发。 end - 没有更多的数据可读时触发。 error - 在接收和写入过程中发生错误时触发。 finish - 所有数据已被写入到底层系统时触发。 从流中读取数据 var fs=require('fs'); var data=''; var readStream=fs.createReadStream('haha.txt'); readStream.setEncoding('UTF8'); readStream.on('data',function(chunk){ data+=chunk; }); readStream.on('end',function(){ console.log(data); }); 写入流 var fs=require('fs'); var data='123456' // 创建一个可以写入的流,写入到文件 haha.txt 中 var writeStream=fs.createWriteStream('haha.txt') // 使用 utf8 编码写入数据 writeStream.write(data,'UTF8'); //标记文件末尾 writeStream.end(); writeStream.on('finish',function(){ console.log("写入完成。"); }); 管道流 管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。 var fs=require('fs'); var readStream=fs.createReadStream('haha.txt'); var writeStream=fs.createWriteStream('note.txt'); // 管道读写操作 // 读取 haha.txt 文件内容,并将内容写入到 note.txt 文件中 readStream.pipe(writeStream); 链式流 链式流一般用于管道操作,类似JQ的链式操作 var fs=require('fs'); var zlib=require('zlib'); var readStream=fs.createReadStream('haha.txt'); var writeStream=fs.createWriteStream('haha.txt.gz'); var createGzip=zlib.createGzip() //压缩 haha.txt 文件为 haha.txt.gz /*readStream.pipe(createGzip).pipe(writeStream)*/ //简写方式: fs.createReadStream('haha.txt').pipe(zlib.createGzip()).pipe(fs.createWriteStream('haha.txt.gz')) ------------------------------------------------------------------------------------------- 函数的传递: function bb(ag1){ console.log(ag1) } function aa(fn,ag2){ fn(ag2); } aa(bb,10) //展开传递函数 (function aa(ag2){ (function bb(ag1){ console.log(ag1) })(ag2) })(10) //匿名函数的传递 aa( function(ag3){console.log(ag3)},20 ) ------------------------------------------------------------------------------------------- 模块加载顺序: http://www.runoob.com/nodejs/nodejs-module-system.html ------------------------------------------------------------------------------------------- Node.js模块系统 为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块, 这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。 Node.js 提供了exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。 //route.js exports.hello=function(){ //输出exports对象 console.log(111); } var aa=require('./aa')//获取exports对象 aa.hello(); //route.js function Hello(){ var height=0; this.setHeight=function(hh){ height=hh; } this.getHeight=function(){ console.log(height); } } module.exports=Hello; //输出Helllo对象 var bb=require('./bb')//获取Hello对象 var hello=new bb(); hello.setHeight(12); hello.getHeight(); ------------------------------------------------------------------------------------------- Node.js 路由 我们要为路由提供请求的URL和其他需要的GET及POST参数,随后路由需要根据这些数据来执行相应的代码。 因此,我们需要查看HTTP请求,从中提取出请求的URL以及GET/POST参数。 //将路由绑定在服务器上 var http=require("http"); var url=require('url'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); var route = url.parse(req.url).pathname; if (route == '/') { res.write('/index') } else if (route == '/about') { res.write('/about') }else{ res.write('/not found 404') } res.end(); }).listen(2000); //使用依赖注入的方式为服务器添加路由模块 1、route.js---路由模块 function route(pathname,res){ if (pathname == '/') { res.write('/index') } else if (pathname == '/about') { res.write('/about') }else{ res.write('/not found 404') } } exports.route=route; //输出路由模块 2、server.js---服务器模块 把路由模块注入到服务器 var http=require("http"); var url=require('url'); function server(route) { http.createServer(function (req,res) { res.writeHead(200, {'Content-Type': 'text/plain'}); var pathname = url.parse(req.url).pathname; route(pathname,res);//通过函数传递的方式把路由模块传进来,并且把response对象传递给路由模块 res.end(); }).listen(2000); } exports.server=server; //输出服务器模块 3.运用 var route=require('./route'); var server=require('./server'); server.server(route.route); ------------------------------------------------------------------------------------------- Node.js 全局对象 JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方 访问,即全局变量。 在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除 了 global 本身以外)都是 global 对象的属性。 __filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文 件名不一定相同。 如果在模块中,返回的值是模块文件的路径。 // 输出全局变量 __filename 的值 console.log( __filename ); __dirname __dirname 表示当前执行脚本所在的目录。 console console 用于提供控制台标准输出,它是由 Internet Explorer 的 JScript 引擎提供的调试工具,后来逐渐成 为浏览器的事实标准。 Node.js 沿用了这个标准,提供与习惯行为一致的 console 对象,用于向标准输出流(stdout)或标准错误流( stderr)输出字符。 console.error([data][, ...]) console.warn([data][, ...]) console.dir(obj[, options]) 用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示。 console.trace():向标准错误流输出当前的调用栈。 process process 是一个全局变量,即 global 对象的属性。 它用于描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口。 exit 当进程准备退出时触发。 process.on('exit', function(code) { console.log(code) } 退出状态码 http://www.runoob.com/nodejs/nodejs-global-object.html Process 属性 execPath 返回执行当前脚本的 Node 二进制文件的绝对路径。 // 平台信息 console.log(process.platform); versions 一个属性,包含了 node 的版本和依赖. pid 当前进程的进程号。 title 进程名,默认值为"node",可以自定义该值。 arch 当前 CPU 的架构:'arm'、'ia32' 或者 'x64' execPath 返回执行当前脚本的 Node 二进制文件的绝对路径。 Process 方法 cwd() 返回当前进程的工作目录 > process.cwd(); 'C:\Windows\system32' memoryUsage() 返回一个对象,描述了 Node 进程所用的内存状况,单位为字节。 > process.memoryUsage(); { rss: 15847424, heapTotal: 5099136, heapUsed: 3829728 } heapTotal代表已申请到的堆内存,heapUsed当前使用的内存,rss(resident set size)进程的常驻内存 uptime() 返回 Node 已经运行的秒数。 > process.pid; 2596 > process.title; '管理员: 命令提示符 - node' > process.kill(2596); kill(pid[, signal]) 发送信号给进程. pid 是进程id,并且 signal 是发送的信号的字符串描述。信号名是字符串,比如 'SIGINT' 或 'SIGHUP'。如果忽略,信号会是 'SIGTERM'。 chdir(directory) 改变当前工作进程的目录,如果操作失败抛出异常。 exit([code]) 使用指定的 code 结束进程。如果忽略,将会使用 code 0。 ------------------------------------------------------------------------------------------- Node.js 常用工具 util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足。 util.inherits util.inherits(constructor, superConstructor)是一个实现对象间原型继承 的函数。 JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同。JavaScript 没有 提供对象继承的语言级别 特性,而是通过原型复制来实现的。 function Aa(){ this.name='zhang'; thia.sayname=function(){ console.log(this.name) } } Aa.prototype.sayhi=function(){ console.log('12345') } Aa.prototype.age=22; function Bb(){ this.name='teng' } var util=require('util'); util.inherits(Bb,Aa); var bb=new Bb(); //bb.sayname();不会继承构造函数里面的属性和方法 bb.sayhi(); console.log(bb)//不会输出继承的原型函数上的方法和属性 Bb 仅仅继承了Aa 在原型中定义的函数,而构造函数内部创造的 name 属 性和 sayname函数都没有被Bb 继承。 同时,在原型中定义的属性不会被console.log 作 为对象的属性输出。 util.inspect util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换 为字符串的方法,通常用于调试 和错误输出。它至少接受一个参数 object,即要转换的对象。 showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息。 depth 表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多 少。如果不指定depth,默 认会递归2层,指定为 null 表示将不限递归层数完整遍历对象。 如果color 值为 true,输出格式将会以ANSI 颜色编码,通常用于在终端显示更漂亮 的效果。 util.inspect(util,true); util.isArray(object) util.isRegExp(object) util.isDate(object) util.isError(object) 如果给定的参数 "object" 是一个数组返回true,否则返回false。 ------------------------------------------------------------------------------------------- Node.js 文件系统 var fs=require('fs'); fs.readFile('n.txt', function (err, data) { if (err) { return console.error(err); } console.log("异步读取: " + data); }); var txt=fs.readFileSync('n.txt'); console.log('同步读取'+txt); 打开文件fs.open(path, flags[, mode], callback) 以下为在异步模式下打开文件的语法格式: 参数使用说明如下: path - 文件的路径。 flags - 文件打开的行为。 mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。 callback - 回调函数,带有两个参数如:callback(err, fd)。 flags: r 以读取模式打开文件。如果文件不存在抛出异常。 r+ 以读写模式打开文件。如果文件不存在抛出异常。 rs 以同步的方式读取文件。 rs+ 以同步的方式读取和写入文件。 w 以写入模式打开文件,如果文件不存在则创建。 wx 类似 'w',但是如果文件路径不存在,则文件写入失败。 w+ 以读写模式打开文件,如果文件不存在则创建。 wx+ 类似 'w+', 但是如果文件路径不存在,则文件读写失败。 a 以追加模式打开文件,如果文件不存在则创建。 ax 类似 'a', 但是如果文件路径不存在,则文件追加失败。 a+ 以读取追加模式打开文件,如果文件不存在则创建。 ax+ 类似 'a+', 但是如果文件路径不存在,则文件读取追加失败。 以下为通过异步模式获取文件信息的语法格式: fs.stat(path, callback) 参数 参数使用说明如下: path - 文件路径。 callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。 fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属 性。 fs.stat('n.txt',function(err,stats){ console.log(stats)//获取文件信息 console.log(stats.isFile());//判断文件类型 }) stats类中的方法有: stats.isFile() 如果是文件返回 true,否则返回 false。 stats.isDirectory() 如果是目录返回 true,否则返回 false。 stats.isBlockDevice() 如果是块设备返回 true,否则返回 false。 stats.isCharacterDevice() 如果是字符设备返回 true,否则返回 false。 stats.isSymbolicLink() 如果是软链接返回 true,否则返回 false。 stats.isFIFO() 如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。 stats.isSocket() 如果是 Socket 返回 true,否则返回 false。 写入文件: fs.writeFile(filename, data[, options], callback) path - 文件路径。 data - 要写入文件的数据,可以是 String(字符串) 或 Buffer(流) 对象。 options - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 'w' callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。 fs.writeFile('n.txt','hello world',{'encoding':'utf-8','flag':'a'},function(err){ if(err){ console.log(err) //如果有错误输出错误信息 } }) 读取文件 fs.read(fd, buffer, offset, length, position, callback) fd - 通过 fs.open() 方法返回的文件描述符。 buffer - 数据写入的缓冲区。 offset - 缓冲区写入的写入偏移量。 length - 要从文件中读取的字节数。 position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。 callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。 var fs=require('fs'); var buf=new Buffer(12); fs.open('n.txt','r+',function(err,fd){ if(err){ console.log('打开文件出错!') }else{ console.log('打开文件成功!') } fs.ftruncate(fd,6,function(err){//截取文件 if(err){ console.log(err) } fs.read(fd,buf,0,buf.length,0,function(err,bytes){//读取文件 if(err){ console.log(err) } console.log(bytes+'字节被读取!');//bytes是返回的字节数 if(bytes>0){ console.log(buf.slice(0,bytes).toString()) } }) fs.close(fd,function(err){ if(err){console.log('关闭失败!')} console.log('关闭成功!') }) }) }) 关闭文件 fs.close(fd, callback) fd - 通过 fs.open() 方法返回的文件描述符。 callback - 回调函数,没有参数。 截取文件 fs.ftruncate(fd, len, callback) fd - 通过 fs.open() 方法返回的文件描述符。 len - 文件内容截取的长度。 callback - 回调函数,没有参数。 删除文件 path - 文件路径。 callback - 回调函数,没有参数。 创建目录 fs.mkdir(path[, mode], callback) path - 文件路径。 mode - 设置目录权限,默认为 0777。 callback - 回调函数,没有参数。 读取目录 fs.readdir(path, callback) path - 文件路径。 callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。 fs.readdir('../',function(err,files){ if (err) { return console.error(err); } console.log(files) }); 删除目录 path - 文件路径。 callback - 回调函数,没有参数。 fs.rename(oldPath, newPath, callback) 异步 rename().回调函数没有参数,但可能抛出异常。 fs.exists(path, callback) 检测给定的路径是否存在。 ------------------------------------------------------------------------------------------- Node.js GET/POST请求 获取GET请求内容 由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括了?后面的部分,因此可以手动解析后面的内容作为GET请求的参数 var url=require('url'); var href='http://www.baidu.com/nangua?wokao=2222'; console.log(url.parse(href).query) 获取POST请求内容 var http=require('http'); var util=require('util'); var querystring=require('querystring'); http.createServer(function(req,res){ var postContent='' res.writeHead(200,{'content-type':'text/plain'}); req.on('data',function(chunk){ postContent+=chunk; }) req.on('end',function(){ postContent=querystring.parse(postContent); res.end(util.inspect(postContent)) }) }).listen(3000) ------------------------------------------------------------------------------------------- Node.js OS 系统操作模块 var os=require('os'); console.log(os.tmpdir())//返回临时文件夹地址 console.log(os.hostname())//返回主机名 console.log(os.type())//返回系统类型Windows_NT或其他 console.log(os.platform())//返回操作系统平台名win32或其他 console.log(os.arch())//返回操作系统 CPU 架构,可能的值有 "x64"、"arm" 和 "ia32"。 console.log(os.release())//返回操作系统的发行版本。 console.log(os.uptime())//返回操作系统运行的时间,以秒为单位。 console.log(os.totalmem())//返回系统内存总量,单位为字节。 console.log(os.freemem())//返回操作系统空闲内存量,单位是字节。 console.log(os.cpus())//返回一个对象数组,包含所安装的每个 CPU/内核的信息:型号、速度(单位 MHz)、时间(一个包含 user、nice、sys、idle 和 irq 所使用 CPU/内核毫秒数的对象)。 console.log(os.networkInterfaces())//获得网络接口列表。 Node.js Path 模块 path.parse(pathString) 返回路径解析对象。 path.format(pathObject) 从对象中返回路径字符串,和 path.parse 相反。 path.extname(p) 返回路径中文件的后缀名,即路径中最后一个'.'之后的部分。如果一个路径中并不包含'.'或该路径只包含一个'.' 且这个'.'为路径的第一个字符,则此命令返回空字符串。 path.basename(p[, ext]) 返回路径中的最后一部分。同 Unix 命令 bashname 类似。 path.dirname(p) 返回路径中代表文件夹的部分,同 Unix 的dirname 命令类似。 path.isAbsolute(path) 判断参数 path 是否是绝对路径。 path.resolve([from ...], to) 转换为绝对路径 path.join([path1][, path2][, ...]) 用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是"/",Windows系统是""。 path.normalize(p) 规范化路径,注意'..' 和 '.'。 var path = require("path") console.log(path.normalize('http://www.baidu.com//hehe'))//http:www.baidu.comhehe console.log(path.join('hehe/','/haha')) //hehehaha console.log(path.resolve('hehe','haha'))//c:UsersAdministratorDesktop esthehehaha console.log(path.isAbsolute('hehe')) //false console.log(path.dirname('hehe/haha')) console.log(path.basename('hehe/haha')) console.log(path.extname('hehe/haha.txt')) console.log(path.parse('hehe/haha'))//{ root: '', dir: 'hehe', base: 'haha', ext: '', name: 'haha' } console.log(path.format({ root: '', dir: 'hehe', base: 'haha', ext: '', name: 'haha' })) ------------------------------------------------------------------------------------------- 创建聊天服务器 //tcp.js var net=require('net')//这个模块包含了Node 需要的所有TCP 功能 var chatServer=net.createServer();//调用net.createServer() 方法来创建一个新的TCP 服务器 on() 方法来添加一个事件监听器。 每当有新的客户端通过网络连接接入服务器,就会触发connection 事件,事件监 听器就会调用我们指定的函数。 连接事件在调用回调函数时,会传给我们新客户端所对应的TCP socket 对象的引 用。我们把此引用命名为client。调用client.write(),就能发送信息给该客户端。 chatServer.on('connection',function(client){ client.write('hello '); }) chatServer.listen(9000) //cmd node tcp telnet localhost 9000 //客户端互相发消息 var net=require('net') var chatServer=net.createServer(); var clientList=[]; chatServer.on('connection',function(client){ client.write('hello '); clientList.push(client); client.on('data',function(data){ for(var i=0;i<clientList.length;i++){ // 把数据发送给所有客户端(包括自己发信息的客户端),没有区分哪些消息是自己发送的,哪些消息是别人发送的 clientList[i].write(data) } }); }) chatServer.listen(9000) //改进客户端互相发消息,区分消息是谁发的,并且不在自己发信息的客户端接收自己刚发送的信息 var net=require('net') var chatServer=net.createServer(); var clientList=[]; chatServer.on('connection',function(client){ clientList.push(client);//断开其中的一个客户端连接,会报错导致所有的客户端退出连接 //client.remoteAddress 是客户端所在的IP地址 //client.remotePort 是客户端接收从服务器返回数据的TCP 端口。 client.name=client.remoteAddress+'--'+client.remotePort client.write('my address is'+client.name+' ')//我的地址 client.on('data',function(data){ for(var i=0;i<clientList.length;i++){ if(client!=clientList[i]){//排除自己 clientList[i].write(client.name+'says:'+data+' ') } } }); }) chatServer.listen(9000) //再改进版,让一个客户端断开的时候,把它从客户端列表中移除,防止它再调用write() 方法 var net=require('net') var chatServer=net.createServer(); var clientList=[]; var cleanup=[]; chatServer.on('connection',function(client){ clientList.push(client); client.name=client.remoteAddress+'--'+client.remotePort client.write('my address is'+client.name+' ')//我的地址 client.on('data',function(data){ for(var i=0;i<clientList.length;i++){ if(client!=clientList[i]){//排除自己 if(clientList[i].writable){//检查socket 是否可写 clientList[i].write(client.name+'says:'+data+' ') }else{ cleanup.push(clientList[i]); cleanup[i].destory(); } } } for(var i=0;i<cleanup.length;i++){//移除不可写的socket clientList.splice(cleanup[i].indeOf(),1) } }); client.on('end',function(client){ clientList.splice(clientList.indexOf(client),1); })//当一个客户端断开时,把它从客户端列表中移除 client.on('error', function(e) { console.log(e) }) }) chatServer.listen(9000)