四、Node基础
node 一般用于中间层、小型服务器、工具类的开发
4.1 npm 基本命令
npm 是 JavaScript 世界的包管理工具,并且是 Node.js 平台的默认包管理工具
- 换源
npm install cnpm -g --registry=https://registry.npm.taobao.org
- 安装
npm install xxxnpm i xxx
- 删除
npm uninstall xxxnpm un xxx
- 更新
npm update xxx
- 初始化项目
-
npm init//package.json { "name": "test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", //npm i koa -d 后会自动生成在这儿 "devDependencies": { "koa": "^2.11.0" // ^ + 兼容版 } }
4.2 node 模块
4.2.1 使用模块
- 引入
带路径需要去路径下找,如果没有从 node_modules 文件夹找,还没有的话会从系统的 node_modules 文件夹找
const xx = require('xx');
- 导出
//mod.js
exports.a = 1;
//app.js
const mod = require('./mod')
console.log(mod.a)
- 批量导出
module.exports = {
a:'1'
};//可以导出json
module.exports = function(){
};//可以导出函数
module.exports = class{
constructor(name){
this.name = name;
}
};//可以导出类
4.2.2 系统模块
- assert 断言
const assert = require('assert');
assert('条件','errlog'); //通过不执行,不通过打印错误日志
//深度比较
assert.deepStrictEqual(变量,预期值,msg)
- path 路径
const path = require('path')
let str = '/root/a/b/1.txt'
console.log(path.dirname(str)) //输出:/root/a/b
console.log(path.extname(str)) //输出:.txt
console.log(path.basename(str))//输出:1.txt
console.log(path.resolve(__dirname,'build'))
//当前目录的绝对路径/build
4.3 数据通信
4.3.1 http 模块
const http = require('http')
let server = http.createServer((req, resp) => {
//服务器返回
resp.write('返回数据');
resp.end()
});
server.listen(8080);
4.3.2 fs 文件读写模块
const fs = require('fs');
//写入相同的文件将会覆盖
fs.writeFile('./test.txt', 'abc你好啊', err => {
if (err) {
console.log("失败")
} else {
console.log("成功")
}
})
fs.readFile('./test.txt', {
encoding: 'utf-8'
}, (err, data) => {
console.log(data)
})
文件流的读写
const fs = require('fs');
const zlib = require('zlib');
let rs = fs.createReadStream('3.txt');
let ws = fs.createWriteStream('2.txt');
//let gz = fs.createGzip(); 压缩
rs.pipe(ws);
//rs.pipe(gz).pipe(ws); 压缩
rs.on('error',err=>{
console.log(err);
});
ws.on('finish',()=>{
console.log('完成');
});
4.3.3 解析get/post请求
- url模块解析 get 请求
const http = require('http');
const url = require('url');
http.createServer((req, resp) => {
let get = url.parse(req.url,true)
console.log(get)
}).listen(8080);
- post 发送的是body,并且可能分批次请求
const http = require('http');
const url = require('url');
const querystring = require('querystring');
let arr=[];
http.createServer((req, resp) => {
req.on('data',buffer=>{
arr.push(buffer)
})
//post请求完毕,将每批的结果拼接起来
req.on('end',()=>{
let buffer = Buffer.concat(arr);
let post = querystring.parse(buffer.toString());
console.log(post);
})
}).listen(8080);
4.3.4 解析文件请求
提交表单
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="file" name="f1">
<input type="submit" value="提交">
</form>
后端处理
const http = require('http');
const multiparty = require('multiparty')
http.createServer((req, resp) => {
let form = new multiparty.Form({
uploadDir: './upload'//上传到的位置
})
form.parse(req);
form.on('field', (name, value) => {
console.log('field', name, value)
})
form.on('file', (name, file) => {
console.log('file', name, file)
})
form.on('close', () => {
console.log("表单解析完成")
})
}).listen(8080);
4.3.5 ajax 跨域问题
原生 ajax 请求
<script>
let btn1 = window.document.getElementById('btn1');
btn1.onclick = () => {
//原生 ajax
let ajax = new XMLHttpRequest();
ajax.open('GET', 'http://localhost:8080/a', true);
ajax.send();
ajax.onreadystatechange = () => {
//0~4
if (ajax.readyState === 4) {
if (ajax.status >= 200 && ajax.status < 300 || ajax.status === 304){
alert('成功');
alert(ajax.responseText);
}else{
alert('失败');
}
}
}
}
</script>
后端给浏览器返回一个声明,解决跨域问题
const http = require('http');
http.createServer((req, resp) => {
let res = {
a: '1',
b: '2'
};
resp.setHeader('access-control-allow-origin', "*"); //解决跨域问题,全部允许
resp.write(JSON.stringify(res));
resp.end();
}).listen(8080);
4.3.6 fetch
fetch 可以解析多种数据,文本、json、图片等
<script>
let btn1 = window.document.getElementById('btn1');
btn1.onclick = async () => {
let result = await fetch('./data/1.json');
// let str = await result.text(); 解析文本
//let json = await result.json(); 解析 json
let blob = await result.blob();
let url = URL.createObjectURL(blob);
}
</script>
4.3.7 FormData(Ajax2.0)
上传表单的新姿势
<script>
//原生
let mForm = document.querySelector('#mform');
mForm.onsubmit = function () {
//拿到form数据
let formdata = new FormData(mForm);
let xhr = new XMLHttpRequest();
xhr.open(formdata.method, formdata.action, true);
xhr.send(formdata)
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert('成功');
} else {
alert('失败');
}
}
}
}
//jquery
$('#mform').on('submit', () => {
let formdata = new FormData(this);
$.ajax({
url: this.action,
type: this.method,
data: formdata,
processData: false,
contentType: false
}).then(success => {
alert('成功');
}, fail => {
alert('失败');
});
});
</script>
4.3.8 webSocket
性能高、双向通信(客户端可以向服务端发请求,服务端也能向客户端主动发数据)、TCP、一对一
安装socket.io:
npm i socket.io -D
客户端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://localhost:8080/socket.io/socket.io.js" charset="utf-8"></script>
</head>
<body>
<script>
let socket = io.connect('ws://localhost:8080');
socket.emit('c2s', 1, 2, 3);
socket.on('s2c', data => {
console.log(data);
})
</script>
</body>
</html>
服务端
const http = require('http');
const io = require('socket.io')
//1.建立普通的 http
let server = http.createServer((req, resp) => {
});
server.listen(8080);
//2.建立webSocket
let webSocketServer = io.listen(server);
webSocketServer.on('connection', socket => {
//主动发送数据
setInterval(()=>{
socket.emit('s2c', new Date().getTime())
},1000);
//接收客户端数据
socket.on('c2s', (data1,data2,data3) => {
console.log(data1,data2,data3);
})
});
4.4 数据库
4.4.1 分类
-
文件型: acess、sqlite;适合单机存储少量数据,容易迁移
-
关系型数据库:MySql、Oracel;支持复杂查询,性能一般
-
分布式:mongoDB;单机性能不高,可以合起来形成存储网络
-
NoSQL:redis;简单查询,性能高
4.4.2 Node 使用数据库
const mysql = require('mysql');
//连接到服务器
let db = mysql.createConnection({
host: 'localhost',
port: 3306,//default
user: 'root',
password: 'root',
database: 'wuai'
});
//查询
db.query('SELECT * FROM user_info', (err, data) => {
console.log(err, data);
});
优化
const http = require('http');
const mysql = require('mysql');
const co = require('co-mysql');
//建立连接池
let conn = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'root',
database: 'wuai'
});
//异步调用
let db = co(conn);
http.createServer(async (req,resp)=>{
let data = await db.query('SELECT * FROM user_info WHERE id = 1');
}).listen(8080);