node.js 是干什么的?
node.js 是一个能在服务端运行的JavaScript
node.js 目录分类
bin:存放真实执行文件 如:www
node_modules:存放当前项目的所有依赖
public:静态资源文件(img.js.css)
routes:项目路由文件
views :页面文件
app.js:项目启动文件
package.json:项目依赖配置及开发者信息
引入一个文件
#引入外部 express文件 默认为js文件
var express=require('express')
函数
#引入外部 express文件
var fs=require("fs");
#读取文件
fs.readFile('input.txt', function (err, data) {
#函数校验
if (err) return console.error(err);
console.log(data.toString());
});
事件
Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件
/ 引入 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("程序执行完毕。");
事件队列触发
当有多个事件时,基于不同的校验处理不同的功能
//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
#判断是哪个事件分别触发
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
#事件参数说明
# on(指定事件) 函数用于绑定事件函数
# emit 属性用于触发一个事件
#addListener(event, listener)
#为指定事件添加一个监听器到监听器数组的尾部。
#如
var callback = function(stream) {
console.log('someone connected!');
};
server.on('connection', callback);
# 移除事件监听器
server.removeListener('connection', callback);
Buffer
# 创建buffer
# 创建一个长度为 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 = Buffer.alloc(256);
len = buf.write("www.runoob.com");
#读取缓冲区
buf = Buffer.alloc(26);
for (var i = 0 ; i < 26 ; i++) {
buf[i] = i + 97;
}
console.log( buf.toString('ascii')); // 输出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5)); //使用 'ascii' 编码, 并输出: abcde
console.log( buf.toString('utf8',0,5)); // 使用 'utf8' 编码, 并输出: abcde
console.log( buf.toString(undefined,0,5)); // 使用默认的 'utf8' 编码, 并输出: abcde
#buf转json
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);
流(Stream)
#从流中读取数据
var fs = require("fs");
var data = '';
// 创建可读流
var readerStream = fs.createReadStream('input.txt');
// 设置编码为 utf8。
readerStream.setEncoding('UTF8');
// 处理流事件 --> data, end, and error
readerStream.on('data', function(chunk) {
data += chunk;
});
readerStream.on('end',function(){
console.log(data);
});
readerStream.on('error', function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
#写入流
var fs = require("fs");
var data = '菜鸟教程官网地址:www.runoob.com';
// 创建一个可以写入的流,写入到文件 output.txt 中
var writerStream = fs.createWriteStream('output.txt');
// 使用 utf8 编码写入数据
writerStream.write(data,'UTF8');
// 标记文件末尾
writerStream.end();
// 处理流事件 --> finish、error
writerStream.on('finish', function() {
console.log("写入完成。");
});
writerStream.on('error', function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
#管道流
#从一个流往另外一个流中写入
var fs = require("fs");
// 创建一个可读流
var readerStream = fs.createReadStream('input.txt');
// 创建一个可写流
var writerStream = fs.createWriteStream('output.txt');
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);
console.log("程序执行完毕");
#链式流
#链式流 主要分为压缩与解压
#压缩
var fs = require("fs");
var zlib = require('zlib');
// 压缩 input.txt 文件为 input.txt.gz
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
console.log("文件压缩完成。");
#解压
var fs = require("fs");
var zlib = require('zlib');
// 解压 input.txt.gz 文件为 input.txt
fs.createReadStream('input.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt'));
console.log("文件解压完成。");
模块系统
模块之间有时需要相互调用,这个时候便需要引入其它模块了
var hello = require('./hello');
hello.world();
# 将对象封装到模块中
//hello.js
function Hello() {
var name;
this.setName = function(thyName) {
name = thyName;
};
this.sayHello = function() {
console.log('Hello ' + name);
};
};
module.exports = Hello;
函数
说明:在 JavaScript中,一个函数可以作为另一个函数的参数。我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数。
Node.js 中函数的使用与 JavaScript 类似,举例
function say(word) {
console.log(word);
}
function execute(someFunction, value) {
someFunction(value);
}
execute(say, "Hello");
路由
定义路径
// 加载所需模块
var http = require('http');
var url = require('url');
var fs = require('fs');
var host = '127.0.0.1';
var port = 8080;
http.createServer(function(req,res){
var pathname = url.parse(req.url).pathname;
console.log('Request for ' + pathname + ' received.');
function showPaper(path,status){
var content = fs.readFileSync(path);
res.writeHead(status, { 'Content-Type': 'text/html;charset=utf-8' });
res.write(content);
res.end();
}
switch(pathname){
//'首页'
case '/':
case '/home':
showPaper('./view/home.html',200);
break;
//'about页'
case '/about':
showPaper('./view/about.html',200);
break;
//'404页'
default:
showPaper('./view/404.html',404);
break;
}
}).listen(port, host);
全局变量&局部变量
全局变量:定义在函数外的变量
局部变量:定义在函数内的变量
Util
工具类,通常能直接用的,比如校验
#判断参数是否是一个数组 util.isArray(args)
var util = require('util');
util.isArray([])
// true
util.isArray(new Array)
// true
util.isArray({})
// false
#util.isRegExp(object)
var util = require('util');
util.isRegExp(/some regexp/)
// true
util.isRegExp(new RegExp('another regexp'))
// true
util.isRegExp({})
// false
#判断参数是否是一个时间 util.isDate(object)
var util = require('util');
util.isDate(new Date())
// true
util.isDate(Date())
// false (without 'new' returns a String)
util.isDate({})
// false
文件系统
文件的数据读取以及相应方法
#文件读取
var fs = require("fs");
// 异步读取
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取: " + data.toString());
});
// 同步读取
var data = fs.readFileSync('input.txt');
console.log("同步读取: " + data.toString());
console.log("程序执行完毕。");
#相应method
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。
Get/Post请求
两者的请求方式不一样
Get 参数暴露,且船数量有限
Post 相当于加密传输,支持大数据传输
工作模块
1 OS 模块
提供基本的系统操作函数。
2 Path 模块
提供了处理和转换文件路径的工具。
3 Net 模块
用于底层的网络通信。提供了服务端和客户端的的操作。
4 DNS 模块
用于解析域名。
5 Domain 模块
简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的
web模块
web模块便是web服务,以http请求为例
Express
提供依赖库,便是node_modules下的依赖。
RESTful API
rest是一种架构风格
GET - 用于获取数据。
PUT - 用于更新或添加数据。
DELETE - 用于删除数据。
POST - 用于添加数据。
JXcore 打包运行
JXcore 是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。
这篇文章主要是要向大家介绍 JXcore 的打包功能。
包代码
例如,我们的 Node.js 项目包含以下几个文件,其中 index.js 是主文件:
rwxr-xr-x 2 root root 4096 Nov 13 12:42 images
-rwxr-xr-x 1 root root 30457 Mar 6 12:19 index.htm
-rwxr-xr-x 1 root root 30452 Mar 1 12:54 index.js
drwxr-xr-x 23 root root 4096 Jan 15 03:48 node_modules
drwxr-xr-x 2 root root 4096 Mar 21 06:10 scripts
drwxr-xr-x 2 root root 4096 Feb 15 11:56 style
接下来我们使用 jx 命令打包以上项目,并指定 index.js 为 Node.js 项目的主文件:
jx package index.js index
以上命令执行成功,会生成以下两个文件:
index.jxp 这是一个中间件文件,包含了需要编译的完整项目信息。
index.jx 这是一个完整包信息的二进制文件,可运行在客户端上。
载入 JX 文件
Node.js 的项目运行:
$ node index.js command_line_arguments
使用 JXcore 编译后,我们可以使用以下命令来执行生成的 jx 二进制文件:
$ jx index.jx command_line_arguments
Node.js Connection Mysql
使用 Node.js 来连接 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);
});
相关参数
host 主机地址 (默认:localhost)
user 用户名
password 密码
port 端口号 (默认:3306)
database 数据库名
charset 连接字符集(默认:'UTF8_GENERAL_CI',注意字符集的字母都要大写)
localAddress 此IP用于TCP连接(可选)
socketPath 连接到unix域路径,当使用 host 和 port 时会被忽略
timezone 时区(默认:'local')
connectTimeout 连接超时(默认:不限制;单位:毫秒)
stringifyObjects 是否序列化对象
typeCast 是否将列值转化为本地JavaScript类型值 (默认:true)
queryFormat 自定义query语句格式化方法
supportBigNumbers 数据库支持bigint或decimal类型列时,需要设此option为true (默认:false)
bigNumberStrings supportBigNumbers和bigNumberStrings启用 强制bigint或decimal列以JavaScript字符串类型返回(默认:false)
dateStrings 强制timestamp,datetime,data类型以字符串类型返回,而不是JavaScript Date类型(默认:false)
debug 开启调试(默认:false)
multipleStatements 是否许一个query中有多个MySQL语句 (默认:false)
flags 用于修改连接标志
ssl 使用ssl参数(与crypto.createCredenitals参数格式一至)或一个包含ssl配置文件名称的字符串,目前只捆绑Amazon RDS的配置文件
数据库操作( CURD )(重点)
查询数据
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '123456',
port: '3306',
database: 'test'
});
connection.connect();
var sql = 'SELECT * FROM websites';
//查
connection.query(sql,function (err, result) {
if(err){
console.log('[SELECT ERROR] - ',err.message);
return;
}
console.log('--------------------------SELECT----------------------------');
console.log(result);
console.log('------------------------------------------------------------\n\n');
});
connection.end();
插入数据
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '123456',
port: '3306',
database: 'test'
});
connection.connect();
var addSql = 'INSERT INTO websites(Id,name,url,alexa,country) VALUES(0,?,?,?,?)';
var addSqlParams = ['菜鸟工具', 'https://c.runoob.com','23453', 'CN'];
//增
connection.query(addSql,addSqlParams,function (err, result) {
if(err){
console.log('[INSERT ERROR] - ',err.message);
return;
}
console.log('--------------------------INSERT----------------------------');
//console.log('INSERT ID:',result.insertId);
console.log('INSERT ID:',result);
console.log('-----------------------------------------------------------------\n\n');
});
connection.end();
更新数据
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '123456',
port: '3306',
database: 'test'
});
connection.connect();
var modSql = 'UPDATE websites SET name = ?,url = ? WHERE Id = ?';
var modSqlParams = ['菜鸟移动站', 'https://m.runoob.com',6];
//改
connection.query(modSql,modSqlParams,function (err, result) {
if(err){
console.log('[UPDATE ERROR] - ',err.message);
return;
}
console.log('--------------------------UPDATE----------------------------');
console.log('UPDATE affectedRows',result.affectedRows);
console.log('-----------------------------------------------------------------\n\n');
});
connection.end();
删除数据
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '123456',
port: '3306',
database: 'test'
});
connection.connect();
var delSql = 'DELETE FROM websites where id=6';
//删
connection.query(delSql,function (err, result) {
if(err){
console.log('[DELETE ERROR] - ',err.message);
return;
}
console.log('--------------------------DELETE----------------------------');
console.log('DELETE affectedRows',result.affectedRows);
console.log('-----------------------------------------------------------------\n\n');
});
connection.end();
MongoDB
MongoDB: https://www.runoob.com/nodejs/nodejs-mongodb.html