node.js
起初的五点是npm的使用,为node实现做基础
- 卸载包命令:npm uninstall 模块名
- 卸载后查看包命令:npm ls
- 更新模块:npm updata 模块名
- 搜索模块:npm search 模块名
创建及发布模块
创建模块,package.json 文件是必不可少的。我们可以使用 NPM 生成 package.json 文件,生成的文件包含了基本的结果。 $ npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg> --save` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. name: (node_modules) runoob # 模块名 version: (1.0.0) description: Node.js 测试模块(www.runoob.com) # 描述 entry point: (index.js) test command: make test git repository: https://github.com/runoob/runoob.git # Github 地址 keywords: author: license: (ISC) About to write to ……/node_modules/package.json: # 生成地址 { "name": "runoob", "version": "1.0.0", "description": "Node.js 测试模块(www.runoob.com)", …… } Is this ok? (yes) yes 以上的信息,你需要根据你自己的情况输入。在最后输入 "yes" 后会生成 package.json 文件。 接下来我们可以使用以下命令在 npm 资源库中注册用户(使用邮箱注册): $ npm adduser Username: mcmohd Password: Email: (this IS public) mcmohd@gmail.com 接下来我们就用以下命令来发布模块: $ npm publish 如果你以上的步骤都操作正确,你就可以跟其他模块一样使用 npm 来安装。
- NPM 常用命令
除了本章介绍的部分外,NPM还提供了很多功能,package.json里也有很多其它有用的字段。
除了可以在npmjs.org/doc/查看官方文档外,这里再介绍一些NPM常用命令。
NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。
NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。
使用npm help <command>可查看某条命令的详细帮助,例如npm help install。
在package.json所在目录下使用npm install . -g可先在本地安装当前命令行程序,可用于发布前的本地测试。
使用npm update <package>可以把当前目录下node_modules子目录里边的对应模块更新至最新版本。
使用npm update <package> -g可以把全局安装的对应命令行程序更新至最新版。
使用npm cache clear可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。
使用npm unpublish <package>@<version>可以撤销发布自己发布过的某个版本代码。 REPL(node自带的交互式解释器)
Node.js REPL(Read Eval Print Loop:交互式解释器) 表示一个电脑的环境,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输入命令,并接收系统的响应。 Node 自带了交互式解释器,可以执行以下任务: 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。 执行 - 执行输入的数据结构 打印 - 输出结果 循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。 Node 的交互式解释器可以很好的调试 Javascript 代码。
- node.js的异步编程的直接提现就是回调,异步编程依托于回调函数实现,单不能说使用回调后程序就异步化了,回调函数在完成任务后就会被调用,node使用了大量的回调函数,node 的所有api都支持回调函数
阻塞代码实例:
var fs = require('fs') var data = fs.readFileSync('input.txt'); console.log(data.toString()); console.log('程序执行结束');
输出结果:
上次吃面是什么时候,你关心吗?
程序执行结束非阻塞代码实例
var fs = require("fs"); fs.readFile('input.txt', function (err, data) { if (err) return console.error(err); console.log(data.toString()); }); console.log("程序执行结束!");
- 阻塞是按照顺序执行的,非阻塞是不需要按顺序执行的,所以如果我们需要处理回调函数参数,我们就需要写到回调函数内
事件循环
- node是单进程单线程应用程序,但是因为V8引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。
- 几乎每个api都是支持回调函数的,
- 几乎所有的事件机制都是用设计模式中观察者模式实现的
- 单线程相当于进入一个while 的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数
事件驱动程序
- node使用事件驱动模型。当web server接收到请求,就把它关闭,然后处理,然后去服务下一个web请求
node有多个内置事件,我们可以通过引入events模块,并通过实例化EventEmitter类来绑定和监听事件,代码如下:
//引入events模块 var events = require('envents'); //创建eventEmitter对象 var eventEmitter = new events.EventEmitter(); // 绑定事件及事件的处理程序 eventEmitter.on('eventName', eventHandler); //我们可通过成序触发事件 eventEmitter.emit('eventName')
- 实例:创建main.js文件,代码如下
// 引入 events 模块 var events = require('events'); // 创建 eventEmitter 对象 var eventEmitter = new events.EventEmitter(); // 创建事件处理程序 var connectHandler = function connected() { console.log('连接成功。'); // 触发 data_received 事件 eventEmitter.emit('data_received'); } // 绑定 connection 事件处理程序 eventEmitter.on('connection', connectHandler); // 使用匿名函数绑定 data_received 事件 eventEmitter.on('data_received', function(){ console.log('数据接收成功。'); }); // 触发 connection 事件 eventEmitter.emit('connection'); console.log("程序执行完毕。");
- node应用程序是如何工作的?
一般情况下将回调函数作为最后一个参数,回调函数接收的错误对象作为第一个参数
node.js EventEmitter
- nide.js所有的异步i/o操作在完成时都会发送一个事件到事件队列
- node里面的很多对象都会分发事件:一个net.Server对象会在每次有新连接的时候触发一个事件,一个fs.readStream对象会在文件被打开的时候触发一个事件,所有这些产生事件的对象都是envents.EventEmitter的实例
EventEmitter类
events模块只提供了一个对象:events.EventEmitter。
EventEmitter的核心就是事件触发和时间监听器功能的封装
可以通过require(‘events’)来访问该模块//引入events模块 var events = require('events') //创建eventEmitter对象 var eventEmitter = new EventEmitter()
EventEmitter对象如果在实例化的时候发生错误,会触发error时间,当添加新的监听事件时,newListener事件会触发,当监听被移除的时候,removeListener事件会触发
// event.js文件 var EventEmitter = require('events').EventEmitter; var event = new EventEmitter() event.on('some_event', function(){ console.log('some_event 事件触发') }) setTimeout(function(){ event.emit('some_event') }, 1000)
EventEmitter 的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持 若干个事件监听器。
当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递
事件的方法及描述
- addListener(event, listener) 为指定事件添加一个监听器到监听器数组的尾部
- on(event, listener) 为指定事件注册一个监听器,接收一个字符和一个回调函数
- once(event, listener) 为指定事件注册一个监听器,即:监听器最多只会触发一次,触发后立即解除该监听器
- removeListener(event, listener) 移除指定事件的某个监听器,该监听器必须是已经被注册过的监听器,它接收两个参数,一个是事件名称,一个是回调函数名称
var callback = function(stream){ console.log('someone connected!') }; server.on('connection', callback) server.removeListener('connection', callback)
- removeAllListener([event]) 移除所有事件的所有监听,如果指定事件,则移除指定事件的所有监听器
- setMaxListener(n) 默认情况下,EventEmitter如果添加的监听超过10个就会输出警报信息,setMaxListners函数用于提高监听器的默认限制的数量
- listeners(event) 返回指定事件的监听器数组
- emit(event, [arg1], [arg2], […]) 按监听器的顺序执行,执行每个监听器,如果事件有注册监听返回true,否则返回false
类方法:
- listenerCount(emitter, event) 返回指定事件的监听器数量
实例说明:
events.EventEmitter.listenerCount(emitter, eventName) //已经废弃,不推荐
events.emitter.listenerCount(eventName) //推荐
- listenerCount(emitter, event) 返回指定事件的监听器数量
事件:
- newListener 该事件在添加新的监听器的时候被触发
- removeListener 从指定监听器数组中删除一个监听器,要注意的是,此操作将改变处于被删除监听器之后的那些监听器的索引
- error事件
EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。
我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃
继承EventEmitter
为什么要这样做呢?原因有两点:
- 首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。
- 其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。
node.js Buff(缓冲区)
1. js自身只有字符串数据类型,没有二进制数据类型
2. 在node.js中,定义了一个buffer类,该类用来创建一个专门存放二进制的数据的缓存区
3. 一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
4. 在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,但是Buffer对内存的权限操作相比很大,可以直接捕获一些敏感信息,所以在v6.0以后,官方文档里面建议使用 Buffer.from() 接口去创建Buffer对象。
buffer与字符编码
buffer实例一般用于表示编码字符的序列,比如UTF-8、UCS2、Base64、或16进制编码的数据。通过显示的字符编码,就可以在buffer实例与普通的js之间进行相互转换
eg:const buf = Buffer.from('runoob', 'ascii'); // 输出 72756e6f6f62 console.log(buf.toString('hex')) // 输出cnVub29i console.log(buf.toString('base64'))
Node.js目前支持的字节编码包括:
- ascii – 仅支持7位ASCII数据。如果设置去掉高位的话,这种编码是非常快的
- utf8 – 多字节编码的Unicode字符,许多网页和其他文档格式都使用UTF-8
- utf16le – 2 或 4 个字节,小字节序编码的Unicode字节,支持代理对(U+10000至U+10FFFF)
- ucs2 – utf16le的别名
- base64编码
- latin1 – 一种把buffer编码成一字节编码的字符串方式
- binary – latin1的别名
- hex – 将每个字节编码为两个16进制字符
创建buffer类
Buffer 提供了以下 API 来创建 Buffer 类:
- Buffer.alloc(size[, fill[, encoding]]): 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
- Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
- Buffer.allocUnsafeSlow(size)
- Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)
- Buffer.from(arrayBuffer[, byteOffset[, length]]): 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。
- Buffer.from(buffer): 复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例
- Buffer.from(string[, encoding]): 返回一个被 string 的值初始化的新的 Buffer 实例
eg: // 创建一个长度为 10、且用 0 填充的 Buffer。 const buf1 = Buffer.alloc(10); // 创建一个长度为 10、且用 0x1 填充的 Buffer。 const buf2 = Buffer.alloc(10, 1); // 创建一个长度为 10、且未初始化的 Buffer。 // 这个方法比调用 Buffer.alloc() 更快, // 但返回的 Buffer 实例可能包含旧数据, // 因此需要使用 fill() 或 write() 重写。 const buf3 = Buffer.allocUnsafe(10); // 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。 const buf4 = Buffer.from([1, 2, 3]); // 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。 const buf5 = Buffer.from('tést'); // 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。 const buf6 = Buffer.from('tést', 'latin1');
写入缓冲区:
语法: buf.write(string, offset[, length])
参数:- string 写入缓冲区
- offset 缓冲区开始写入的索引值
- length 写入的字节数,默认为buffer.length
- encoding 使用的编码,默认为’utf8′
从缓冲区读取数据
语法: buf.toString([encoding[, start[, end]]])
参数:- encoding 使用的编码。默认是’utf-8′
- start 指定开始读取的索引的位置,默认为0
- end 结束位置,默认为缓冲区的末尾
返回值:
解码缓冲区数据并使用指定的编码返回字符串
将buffer转换为json对象
语法:buf.toJSON()注意:当字符串转化一个Buffer实例的时候,JSON.string()会隐式地调用该toJSON()
返回值:返回json对象
缓冲区合并
语法:Buffer.concat(list[, totalLength])
参数:- list:用于合并的buffer对象数组列表
- totalLength: 指定合并后buffer对象的总长度
返回值:
返回一个多成员合并的新buffer对象
缓冲区比较
语法:该语法在node.js v-0.12.2引入buf.compare(otherBuffer)
参数:
- otherBuffer:与buf比较的另一个Buffer对象
返回值:
返回一个数字,表示buf在otherBuffer之前(返回负值),之后(返回正值)或者相同(返回0)
拷贝缓冲区
语法:buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
参数:- targetBuffer:要拷贝的buffer对象
- targetStart:数字可选,默认为0
- sourceStart:数字,可选,默认为0
- sourceEnd:数字可选,默认为buffer.length
返回值:
没有返回值
- 缓冲区剪裁
语法:buf.slice([start[, end]])
参数:1. start:数字,可选,默认为0 2. end:数字可选,默认为buffer.length
返回值:返回一个新的缓冲区,它和旧的缓冲区指向同一块内存,但是是从start到end的位置剪裁 - 缓冲区长度:
语法:buf.length
返回值:返回buffer对象所占据的内存长度 - buffer的参考手册,很多很多。。。。。。。
node.js Stream(流)
- Stream是一个抽象的接口,node中很多对象实现了这个接口,eg:对http服务器发起请求的request对象就是一个Stream,还有stdout(标准输出流)
node.js有四种流类型:
- Readable: 可读操作
- Write:可写操作
- Duplex:可读可写操作
- Transform:操作被写入数据,然后读出结果
所有的Stream对象都是EventEmitter的实例,常用的事件有:
- data:当有数据的时候触发
- end:没有更多数据可读时触发
- error:在接收和写入过程中发生错误时触发
- 所有数据已被写入到底层系统时触发
node.js 常用工具
- util是一个nodejs核心模块,提供常用函数的集合,用于弥补和次年js的功能过于精简不足
- util.inherits(constructor, superConstructor) 是一个实现对象间原型继承的函数。
- 重点:JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同。JavaScript 没有提供对象继承的语言级别特性,而是通过原型复制来实现的。
nodejs文件系统
- nodejs提供了一组类似unix标准的文件操作api,node导入文件系统模块的方法如下:
var fs = require(‘fs’)
2.异步和同步:
Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。
建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。
同步和异步读取:
var fs = require('fs') // 异步读取 fs.readfile('input.txt', function(err, data){ if(err){ return console.error(err) } console.log('异步读取'+data.toString) }) // 同步读取 fs.readFileSync('input.txt') console.log('同步读取'+ data.toString) console.log('程序结束')
打开文件
语法:fs.open(path, flags[, mode], callback)
参数:- path:文件路径
- flages:文件打开的行为
- mode:设置文件模式(权限),文件创建默认权限为0666(可读可写)
- callback:回调函数,带有两个参数:callback(err,fd)
获取文件信息
语法:fs.stat(path, callback)
参数:- path:文件路径
- callback:回调函数,带有两个参数如:(err,stats),state是fs.Stats对象
写入文件
语法:fs.writeFile(file, data[, options], callback)
注意:writeFile 直接打开文件默认是 w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。
参数:- file:文件名或者文件描述符
- data:要写入文件的数据,可以是string字符串或者buffer(缓冲)对象
- option:改参数是一个对象,包含{encoding,mode,flag},默认编码为utf8,模式为0666,flag为’w’
- callback: 回调函数,只包含错误信息参数(err),在写入失败时返回
读取文件:
语法:fs.read(fd, buffer, offset, length, position, callback)
注意:writeFile 直接打开文件默认是 w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。
参数:- fd: 通过fs.open()方法返回的文件描述符
- buffer:数据写入的缓冲区
- offset:缓冲区写入的写入便宜量
- length:要从文件中读取的字节数
- position:文件读取的起始位置,如果position的值为空,则会从当前指针位置读取
- callback:有三个参数,err:错误信息,bytesRead表示读取的字节数,buffer为缓冲区对象
- 关闭文件
- 删除文件
- 截取文件
- 创建目录
- 读取目录
- 删除目录
- 文件模块方法参考shouce
nodejs get/post请求
- 在很多场景中,我们服务器都需要跟用户的浏览器打交道,如:表单提交,表单提交到服务器一般都需要使用get/post请求
- 获取get请求内容
- 获取post请求内容
nodejs 工具模块
几种常见的模块使用
- os模块:提供基本的系统操作函数
- path模块:提供了处理和转换文件路径的工具
- Net模块:用于底层的网络通信,提供服务端和客户端的操作
- DNS模块:用于解析域名
- Domain模块:简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的
nodejs web模块
- 什么是web服务器?
web服务器一般指的是网站服务器,是指驻留在因特网上的某种类型的计算机的程序,web服务器的基本功能就是提供web信息信息浏览服务,他只需支持http服务,html文档格式及url,与客户端的网络浏览器配合
大多数web服务器都支持服务端的脚本语言(php、python、ruby)等,并通过脚本语言从数据库读取数据,将结果返回给客户端浏览器,目前最流行的是三个服务器是Apache、nginx、IIS web应用架构
- client:客户端,一般指浏览器,浏览器一般可以通过http协议向服务器请求数据
- server:服务端,一般指web服务器,可以接收客户端请求,并向客户端发送相应数据
- Business:业务层,通过web服务器处理应用程序,如:与数据库交互,逻辑运算调用外部程序等
- data:数据层,一般有数据库组成
使用node创建web服务器
- node.js提供了http模块,http模块主要用于搭建HTTP服务端和客户端,使用HTTP服务器或客户端功能必须调用HTTP模块:var http = require(‘http’);
nodejs Express 框架
简介:是一个简洁灵活的nodejs web引用框架,可以帮助我们创建web应用和http工具,使用它可以快速搭建一个完整功能的网站,它的核心特点是:
- 可以设置中间件来相应http请求
- 定义了路由表用于执行不同的http请求
- 可以通过向模板传递参数来动态渲染html页面
安装Express
- 将其保存在依赖列表中:$ cnpm install express –save
以上命令会将 Express 框架安装在当前目录的 node_modules 目录中, node_modules 目录下会自动创建 express 目录。以下几个重要的模块是需要与 express 框架一起安装的:
- body-parser – node.js 中间件,用于处理 JSON, Raw, Text 和 URL 编码的数据。
- cookie-parser – 这就是一个解析Cookie的工具。通过req.cookies可以取到传过来的cookie,并把它们转成对象。
- multer – node.js 中间件,用于处理 enctype=”multipart/form-data”(设置表单的MIME编码)的表单数据。
- 请求和响应:express应用使用回调函数的参数:request和response对象来处理请求和响应的数据
app.get('/', function(req, res){ // -- })
对request和response对象的具体介绍:
- Request 对象 – request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:
… - Response 对象 – response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:
…
路由:
我们已经了解了 HTTP 请求的基本应用,而路由决定了由谁(指定脚本)去响应客户端请求。
在HTTP请求中,我们可以通过路由提取出请求的URL以及GET/POST参数。
接下来我们扩展 Hello World,添加一些功能来处理更多类型的 HTTP 请求。
node.js JXcore 打包
- nodejs是一个开放源代码、跨平台的、用于服务端和网络应用的运行环境
- JXcore是一个支持多线程的nodejs发行版本,基本不用对你现有的代码做任何改动就可以直接线程安全的以多线程运行
- JXcore安装
nodejs Mysql 安装
- 安装驱动:npm install mysql
连接数据库: 根据实际的配置修改数据库的用户名、密码、及数据库名
var mysql = require('mysql') var connection = mysql.createConnection({ host: 'localhost', user: 'root', password: '123456', database: 'test' }) connection.connect() connection.query('SELECT 1 + 1 AS solution', function(error, results, fields){ if(error) throw error; console.log('The solution is: ', results[0].solution) })
输出结果:The solution is: 2
数据库参数说明:
- host:主机地址
- user:用户名
- password:密码
- port:端口号(默认:3306)
- database:数据库名
- chartset:连接字符集(默认:UTF8_GENERAL_CL, 注意:字符集的字母都要大写)
- localAddress:此IP用于TCP连接(可选)
- socketPath:连接到unix域路径,当使用host和post时会被忽略
- timeZone:时区(默认local)
- connectTimeout:连接超时
- stringifyObjects:是否序列化对象
- typeCast:是否将列值转化为本地的js类型值(默认为true)
- queryFormat:自定义的query语句格式化方法
- supperBigNumbers:数据库支持bigInt和decimal类型列时,需要设置此option为true(默认false)
- bigNumberStrings:supportBigNumbers和bigNumberStrings启用 强制bigint或decimal列以JavaScript字符串类型返回(默认:false)
- dataStrings:强制timestamp,datetime,data类型以字符串类型返回,而不是JavaScript Date类型(默认:false)
- debug:开启调试(默认false)
- multipleStatements:是否允许一个query中有多个mysql语句
- flags:用于修改连接标志
- ssl:使用ssl参数(与crypto.createCredenitals参数格式一至)或一个包含ssl配置文件名称的字符串,目前只捆绑Amazon RDS的配置文件
nodejs 连接mongoDB
- mongoDB是一种文档导向数据库管理系统,由c++撰写成
- 安装驱动,实现数据库的连接,增删改查