QX-AI初始化中...
暂无预设简介,请点击下方生成AI简介按钮。
初识
NodeJS是使用C++编写的基于ChromeV8引擎,开源、跨平台的JavaScript运行环境
中文API文档
Buffer
Buffer(缓冲区)存放二进制数据的缓存区,类似数组Array
1 2
| let buf = Buffer.alloc(10); let buf_2 = Buffer.allocUnsafe(10);
|
字符串转二进制编码,每个字符按编码转为二进制存入
1 2 3
| let buf_3 = Buffer.from('hello'); console.log(buf_3);
|
将数组存入Buffer
1 2 3
| let buf_4 = Buffer.from([111, 112, 113, 114]); console.log(buf_4);
|
toString()
Buffer转字符串
1 2 3
| let buf_4 = Buffer.from([111, 112, 113, 114]); console.log(buf_4.toString());
|
使用下标访问Buffer
1 2 3 4 5
| let buf_5 = Buffer.from('chuckle'); console.log(buf_5[0]); console.log(buf_5[0].toString(2)); buf_5[0] = 90; console.log(buf_5[0]);
|
溢出,舍弃高位
1 2 3
| buf_5[0] = 360; console.log(buf_5[0]); console.log(buf_5[0].toString(2));
|
Buffer存中文,UTF-8中一汉字占三个字节
1 2 3 4
| let buf_6 = Buffer.from('今天你好'); buf_6.write('轻笑'); console.log(buf_6); console.log(buf_6.toString());
|
fs模块
文件系统(fs 模块)中的方法均有异步和同步版本,异步有回调函数,参数为err错误信息
创建 text.txt 并写入内容
1 2 3 4 5 6 7 8 9 10 11 12
| const fs = require('fs');
fs.writeFile('./text.txt', '轻笑chuckle', err => { if(err){ console.log(err); return; } console.log('成功'); });
fs.writeFileSync('./text.txt', '轻笑chuckle');
|
appendFile
追加写入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| fs.appendFile('./text.txt', '\r\n追加内容', err => { if(err){ console.log(err); return; } console.log('成功'); });
fs.writeFile('./text.txt', '\r\n追加内容',{flag: 'a'} , err => { if(err){ console.log(err); return; } console.log('成功'); });
|
createWriteStream
流式写入,适合频繁或大文件写入,与文件的连接不断开
1 2 3 4 5
| const ws = fs.createWriteStream('.text.txt'); ws.write('1'); ws.write('2'); ws.write('3'); ws.close();
|
readFile
文件读取
1 2 3 4 5 6 7 8 9 10 11 12
| fs.readFile('./text.txt', (err, data)=>{ if(err){ console.log(err); return; } console.log(data.toString()); });
let data = fs.readFileSync('./text.txt'); console.log(data.toString());
|
createReadStream
流式读取
1 2 3 4 5 6 7 8 9
| const rs = fs.createReadStream('./1.mp4'); rs.on('data', chunk =>{ console.log(chunk); console.log(chunk.length); }); rs.on('end', ()=>{ console.log('读取完成'); });
|
复制文件,使用流式操作更快,占用内存更少
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| fs.readFile('./text.txt', (err, data) =>{ if(err){ return console.error(err); } fs.writeFile('./text2.txt', data, err =>{}); });
const rs = fs.createReadStream('./1.mp4'); const ws = fs.createWriteStream('./2.mp4'); rs.on('data', chunk =>{ ws.write(chunk); });
rs.pipe(ws);
|
rename
文件重命名和移动
1 2
| fs.rename('./1.mp4', './3.mp4', err=>{}); fs.rename('./3.mp4', './mp4/3.mp4', err=>{});
|
unlink
删除文件
1 2
| fs.unlink('./2.mp4', err=>{}); fs.rm('./2.mp4', err=>{});
|
mkdir
创建文件夹
1 2 3
| fs.mkdir('./a', err=>{});
fs.mkdir('./a/b/c', {recursive: true},err=>{});
|
readdir
读取文件夹,读取到一个目标文件夹下文件名的数组
1 2 3
| fs.readdir('./mp4', (err, data)=>{ console.log(data); });
|
rmdir
删除文件夹
1 2 3 4 5
| fs.rmdir('./a/b/c', err=>{});
fs.rmdir('./a', {recursive: true},err=>{});
fs.rm('./a',{recursive: true} ,err=>{});
|
stat
查看资源状态
1 2 3 4 5
| fs.stat('./3.mp4', (err, data)=>{ console.log(data); console.log(data.isDirectory()); console.log(data.isFile()); });
|
__dirname 保存js文件所在目录的绝对路径,避免工作路径不同、工作区不同,导致相对路径不同而出bug
1
| fs.writeFileSync(__dirname + '/1.txt', 'chuckle');
|
批量重命名文件,在文件名前加上0
1 2 3 4 5 6 7 8 9 10 11
| fs.readdir(__dirname + '/rename', (err, data)=>{ data.forEach((item, index)=>{ let data = item.split('.'); let [num, suffix] = data; if(Number(num)<10){ num = '0' + num; } fs.renameSync(`${__dirname}/rename/${item}`, `${__dirname}/rename/${num}.${suffix}`); }); });
|
path模块
resolve
拼接规范的绝对路径
1 2 3
| const path = require('path'); let path1 = path.resolve(__dirname + '/rename'); console.log(path1);
|
其它方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| console.log(path.sep);
console.log(path.parse(__filename));
console.log(path.basename(__filename));
console.log(path.dirname(__filename));
console.log(path.extname(__filename));
|
http模块
搭建http服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const http = require('http');
const server = http.createServer((request, response)=>{ response.setHeader('Content-Type', 'text/html; charset=utf-8'); response.end('你好'); });
server.listen(9000, ()=>{ console.log('服务启动'); });
|
获取请求报文
获取请求行和请求头,修改createServe的回调函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const server = http.createServer((request, response)=>{ console.log(request.method); console.log(request.url); console.log(request.httpVersion); console.log(request.headers); console.log(request.headers.host); response.end('hello world'); });
|
获取请求体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const server = http.createServer((request, response)=>{ let body = ''; request.on('data', chunk=>{ body += chunk; }) request.on('end', ()=>{ console.log(body); response.end('hello http'); }); });
|
获取请求路径和查询字符串
使用url模块获取请求路径和查询字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const url = require('url'); const server = http.createServer((request, response)=>{ console.log(request.url); let res = url.parse(request.url, true); console.log(res); console.log(res.path); console.log(res.query); console.log(res.query.psw); });
|
使用URL类获取请求路径和查询字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const server = http.createServer((request, response)=>{ let url = new URL(request.url, 'http://127.0.0.1:9000'); console.log(url); console.log(url.pathname); console.log(url.searchParams); console.log(url.searchParams.get('psw')); });
|
请求路径练习
根据请求路径响应不同内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const http = require('http'); const server = http.createServer((request, response)=>{ let url = new URL(request.url, 'http://127.0.0.1:9000'); let {method} = request; let {pathname} = url; if (method === 'GET' && pathname === '/login'){ response.end('login'); }else if (method === 'GET' && pathname === '/reg'){ response.end('reg'); }else{ response.end('Not Found'); } }); server.listen(9000, ()=>{ console.log('服务启动'); });
|
设置响应报文
设置响应码、响应头、响应体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const http = require('http'); const server = http.createServer((request, response)=>{ response.statusCode = 200; response.statusMessage = 'chuckle'; response.setHeader('Content-Type', 'text/html; charset=utf-8'); response.setHeader('Server', 'nodejs'); response.setHeader('MyHeader', 'chuckle'); response.setHeader('test', ['a', 'b', 'c']); response.write('chuckle'); response.write('qx'); response.end(); });
server.listen(9000, ()=>{ console.log('服务启动成功'); });
|
配合fs模块响应文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| const http = require('http'); const fs = require('fs');
const server = http.createServer((request, response)=>{ let html = fs.readFileSync(__dirname + '/2.html'); response.write(html); response.end(); });
server.listen(9000, ()=>{ console.log('服务启动成功'); });
|
响应文件练习
根据文件路径响应不同内容,下面这种写法不方便,后面有优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const http = require('http'); const fs = require('fs');
const server = http.createServer((request, response)=>{ let html = fs.readFileSync(__dirname + '/2.html'); let css = fs.readFileSync(__dirname + '/2.css'); let url = new URL(request.url, 'http://127.0.0.1:9000'); let {pathname} = url; if(pathname === '/'){ response.write(html); }else if(pathname === '/2.css'){ response.write(css); }else { response.statusCode = 404; response.write('404'); } response.end(); });
server.listen(9000, ()=>{ console.log('服务启动成功'); });
|
优化版:静态资源响应服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const http = require('http'); const fs = require('fs');
const server = http.createServer((request, response)=>{ let url = new URL(request.url, 'https://127.0.0.1:9000'); let {pathname} = url; let root = __dirname; let filePath = root + pathname; fs.readFile(filePath, (err, data)=>{ if(err){ response.statusCode = 404; response.write('404'); response.end(); return; } response.write(data); response.end(); }); });
server.listen(9000, ()=>{ console.log('服务启动成功'); });
|
设置资源mime类型
mime类型用于表示文档、文件或字节流的性质和类型
HTTP服务可以设置响应头 Content-Type 来表明响应体的mime类型,浏览器会根据该类型决定如何处理资源
常见mime类型:
1、html text/html
2、css text/css
3、js text/javascript
4、png image/png
5、jpg image/jpeg
6、gif image/gif
7、mp4 video/mp4
8、mp3 audio/mpeg
9、json application/json
对于未知的资源类型,可以选择 application/octet-stream 刘览器在遇到该类型的响应时,会对响应体内容进行独立存储,实现下载效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| const http = require('http'); const fs = require('fs'); const path = require('path'); let mime = { html: 'text/html;charset=utf-8', css: 'text/css', js: 'text/javascript', png: 'image/png', jpg: 'image/jpeg', gif: 'image/gif', mp4: 'video/mp4', mp3: 'audio/mpeg', json: 'application/json', other: 'application/octet-stream' }
const server = http.createServer((request, response)=>{ let url = new URL(request.url, 'https://127.0.0.1:9000'); let {pathname} = url; let root = __dirname; let filePath = root + pathname; fs.readFile(filePath, (err, data)=>{ if(err){ response.statusCode = 404; response.write('404'); response.end(); return; } let ext = path.extname(filePath).slice(1); let type = mime[ext] ? mime[ext] : mime[other]; console.log(type); response.setHeader('Content-Type', type); response.write(data); response.end(); }); });
server.listen(9000, ()=>{ console.log('服务启动成功'); });
|
完善错误处理
Node.js常见系统错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| const http = require('http'); const fs = require('fs'); const path = require('path'); let mime = { html: 'text/html;charset=utf-8', css: 'text/css', js: 'text/javascript', png: 'image/png', jpg: 'image/jpeg', gif: 'image/gif', mp4: 'video/mp4', mp3: 'audio/mpeg', json: 'application/json', other: 'application/octet-stream' } let errs = { ENOENT: 404, EPERM: 403 }
const server = http.createServer((request, response)=>{ response.setHeader('Content-Type', 'text/html; charset=utf-8'); console.log(request.method); if(request.method !== 'GET'){ response.statusCode = 405; response.end('出错了'); return; } let url = new URL(request.url, 'https://127.0.0.1:9000'); let {pathname} = url; let root = __dirname; let filePath = root + pathname; fs.readFile(filePath, (err, data)=>{ if(err){ let errCode = errs[err.code] ? errs[err.code] : 500; console.log(errCode); response.statusCode = errCode; response.write('出错了'); response.end(); return; } let ext = path.extname(filePath).slice(1); let type = mime[ext] ? mime[ext] : mime[other]; response.setHeader('Content-Type', type); response.write(data); response.end(); }); });
server.listen(9000, ()=>{ console.log('服务启动成功'); });
|
模块化
将一个复杂的程序文件,按一定规则拆分为多个文件,即模块化,每个小文件就算一个模块
模块内部数据是私有的,但可以主动度外暴露出去
模块化项目:
编写项目时一个个模块编写,再组合起来
模块化优点:
1、防止命名冲突
2、高服用性
3、高维护性
暴露数据
在模块中使用module.exports
和exports
向外暴露数据,但两者不能同时使用
隐式关系:exports = module.exports = {}
1 2 3 4 5 6 7 8 9 10 11
| let name = 'chuckle'; let age = 19; function fun() { console.log(name); } module.exports = { name, fun } exports.age = age;
|
导入模块
- 导入js/sjon文件或c编写的mode扩展插件可以省略后缀,同名优先导入js
- 导入自己的模块最好使用相对路径 ./
- 导入其它类型的文件会以js文件处理
- 导入文件夹,首先会去找文件夹内package.json里main属性对应的文件,如果没用main属性或package.json则去找文件夹内的index.js或index.json,如果还没找到则报错,main属性对应的文件不存在也会报错
- 导入nodejs内置模块时,直接写模块名即可
1 2
| const mod = require('./1.js'); const mod = require('./1');
|
包管理工具
包,即package,是一组特定功能的源码集合,即别人写好的各种工具
管理包,即对包进行下载、安装、删除、上传操作
常见包管理工具:npm、yarn、cnpm
npm
Node Package Manager即npm,是nodejs内置的包管理工具
package.json 是包必须有的配置文件
package-lock.json 存放依赖包的版本信息
require导入npm包流程:
1、在当前文件夹下的node_modules中找同名文件夹
2、在上级目录中node_modules中找同名文件夹,直到磁盘根目录
1 2
| npm i <包名@版本号> npm r <包名>
|
npm配置命令别名,修改package.json的 scripts 属性,通过npm run <命令名>运行命令,会自动向上寻找,添加start属性,可以省略run,直接npm start
1 2 3 4 5 6 7 8 9
| "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "server": "node ./index.js", "start": "node ./index.js" },
npm run server npm start
|
通过指定源来提高包安装速度
1
| npm i <包名> --registry=https:
|
开发和生产依赖
开发环境:写源代码、工程文件时的环境,一般指程序员的电脑,只能由程序员访问
生产环境:项目代码正式运行的环境,一般指服务器,所有用户都能访问
开发依赖:只在写代码时用到的依赖包,安装时添加 -D 或 —save-dev
生产依赖:默认项,既在写代码时使用,又在代码运行时使用的依赖包,安装时添加 -S 或 —save 参数,
package.json中,dependencies属性保存生产依赖包信息,devDependencies属性保存开发依赖包信息
全局安装
开发和生产依赖都是局部安装的包,存放在工作目录的node_modules文件夹中
全局安装 npm i -g 不受工作目录位置限制,无需导入,一般是在命令行中通过独立命令去使用
npm root -g 查看全局安装包的位置
只有全局类的工具如 gulp、nodemon等才适合全局安装,通过查看包的文档来确定安装方式
cnpm
cnpm—npmmirror镜像站
使用方式和npm一样,是淘宝构建的完整 npmjs.org 镜像,了解即可,大多还是使用npm
修改npm的源地址来使用淘宝镜像
1 2 3 4 5 6 7 8 9 10 11 12
| npm config list
npm config set registry https:
npm i <包名> --registry=https:
npm i -g nrm nrm use taobao nrm ls npm install -g nrm open@8.4.2 --save
|
yarn
yarn 是由 Facebook 在 2016 年推出的新的 Javascript 包管理工具
yarn和npm需要按需选用,包管理工具不能混用,yarn的锁文件是yarn.lock
npm i -g yarn
安装yarn
常用命令:
- 初始化 yarn init / yarn init -y
- 安装包
- yarn add <包名> 生产依赖
- yarn add <包名> —dev 开发依赖
- yarn global add <包名> 全局安装,第一次使用记得手动配置环境变量
- 删除包
- yarn remove uniq 删除项目依赖包
- yarn global remove nodemon 全局删除包
- 安装项目依赖 yarn
- 运行命令别名 yarn <别名>
- 全局安装包的位置 yarn global bin
管理npm包
- 修改 package.json 中的版本号
- npm publish 提交包
- npm unpublish —force 删除包
nvm管理node版本
nvm 全称 Node Version Manager 用来管理 node 版本的工具
常用命令:
- nvm list available 显示所有可以下载的 Node.js 版本
- nvm list 显示已安装的版本
- nvm install 18.12.1 安装 18.12.1 版本的 Node.js
- nvm install latest 安装最新版的 Node.js
- nvm uninstall 18.12.1 删除某个版本的 Node.js
- nvm use 18.12.1 切换 18.12.1 的 Node.js
设置下载node的镜像
1
| export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node/
|