一、NodeJS入门
1.1 node.js介绍
- 官网:node
- 概念:一个开源的,跨平台的JavaScript运行环境
- 作用:
- 开发服务器应用(返回页面,接口)
- 开发工具类应用(webpack,vite,babel)
- 开发桌面端应用(VsCode,Postman通过electron框架)
- 安装:
- 下载:node
- 配置环境变量:[Path]:D:\software\node
- 注意事项:
- Node.js中不能使用BOM和DOM的API,可以使用console和定时器
- Node.js中的顶级对象是global(也可以使用globalThis访问)
- Node API:fs,url,http,util,console,定时器,path等
二、fs模块(实现与硬盘的交互)
2.1 文件写入
- 相关Api:
- 写入数据:writeFile/writeFileSync(异步/同步)
- 追加数据:appendFile/appendFileSync(异步/同步) 或 writeFile(‘’, ‘’, { flag: ‘a’ }, err=> {})
- 流式写入:createWriteStream
- 区分:
- 流式写入:适合大文件写入或者频繁写入
- writeFile:写入频率较低的场景
- 写入场景:下载文件,安装软件,保存程序日志(git),编辑器保存文件
2.2 文件读取
- 相关Api:readFile/readFileSync/createReadStream(流式读取)
- 应用场景:程序运行,编辑器打开文件,查看图片,播放音乐等
- 区别:
- createReadStream:按块(chunk)读取文件,可以实时处理(适合大文件读取)
- readFile:一次性读取整个文件
2.3 文件移动与命名
2.4 文件删除
- 相关Api:unlink/unlinkSync/rm
2.5 文件夹操作
- 相关Api:
- 创建文件夹:mkdir/mkdirSync
- 读取文件夹:readdir/readdirSync
- 删除文件夹:rmdir/rmdirSync/rm(推荐使用)
2.6 查看资源状态
- 相关Api:stat/statSync
- 作用:获取文件相关信息(文件大小,创建时间等)
2.7 fs路径问题
- 绝对路径
- D:/Program Files // windows系统下的绝对路径
- /ues/bin // Linux系统下的绝对路径 - 盘符的根路径
- 相对路径
- ./1.txt // 当前目录下的1.txt
- 1.txt // 等同于上面
- ../1.txt // 当前目录上一级目录中的1.txt
- 注意:
- 相对路径中所谓的当前目录,指的是命令行的工作目录,而非是文件的所在目录
- 当前命令行的目录与文件目录不一致会出现bug
- __dirname:
- 概念:__dirname当前文件所在目录的绝对路径,可使用__dirname与文件名拼接成绝对路径
- 使用:
// 当前命令行的目录与文件目录不一致会出现bug
const fs = require('fs');
fs.writeFile('./data.txt', 'hello', err => {
if (err) {
console.log(err);
return;
}
console.log('写入成功')
})
// 解决方式使用dirname
const fs = require('fs');
fs.writeFile(__dirname + '/data.txt', 'hello', err => {
if (err) {
console.log(err);
return;
}
console.log('写入成功')
})
2.8 相关示例
<!-- 方法1 - 异步写入 -->
// 1.导入fs模块
const fs = require('fs');
// 2.写入文件(如果没有文件创建一个文件)
fs.writeFile('./data.txt', 'hello world', { flag: 'w' }, err => {
// err 写入失败:错误对象。写入成功:null
if (err) {
console.error(err);
}
console.log('写入成功')
})
<!-- 方法2 - 同步写入 -->
// fs.writeFileSync('./data.txt', '你好,世界');
<!-- 方法3 - 流式写入 -->
const fs = require('fs');
let ws = fs.createWriteStream('./诗歌.txt');
ws.write('轻轻的我走了,\r\n');
ws.write('正如我轻轻的来');
// ws.end();
<!-- 方法1 - 同步读取 -->
const fs = require('fs');
let data = fs.readFileSync('./诗歌.mp4');
fs.writeFileSync('./诗歌-1.mp4', data);
<!-- 方法2 - 流式读取 -->
const fs = require('fs');
const rs = fs.createReadStream('./诗歌.txt');
const ws = fs.createWriteStream('./诗歌-1.txt');
rs.on('data', chunk => {
// 分块读取,执行多次,每次读取64k
ws.write(chunk)
})
rs.on('end', () => {
// 可通过rss查看进程占用的物理内存总量(单位:字节)
console.log(process.memoryUsage());
})
<!-- 方法3 - 流式读取pipe -->
const fs = require('fs');
const rs = fs.createReadStream('./诗歌.txt');
const ws = fs.createWriteStream('./诗歌-1.txt');
rs.pipe(ws)
const fs = require('fs');
fs.rename('./1.txt', './remove/1-1.txt', err => {
if (err) {
console.error(err);
}
console.log('移动重命名成功')
})
// fs.renameSync('./1.txt', './remove/1-1.txt')
const fs = require('fs');
// 方法一
fs.unlink('./remove/1-1.txt', err => {
if(err) {
console.error(err);
}
console.log('文件删除成功');
})
// 方法二
fs.unlinkSync('./remove/1-1.txt')
// 方法三
fs.rm('./remove/1-1.txt', err => {
if(err) {
console.error(err);
}
console.log('文件删除成功');
})
const fs = require('fs');
// 1.通过recursive递归创建
fs.mkdir('./a/b/c', { recursive: true }, err => {
if (err) {
console.error(err);
return;
}
console.log('递归创建成功');
})
// 2.读取当前文件夹下的文件名称
fs.readdir('./', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
})
// 3.递归删除文件
fs.rm('./a', { recursive: true }, err => {
if (err) {
console.error(err);
return;
}
console.log('递归删除成功');
})
const fs = require('fs');
fs.stat('./data.txt', (err, data) => {
if(err) {
console.log(err);
return;
}
// 获取文件相关信息
console.log(data) // size atime等
console.log(data.isFile())
console.log(data.isDirectory())
})
// 1.文件写入.js => 01.文件写入.js
// 2.文件写入.js => 02.文件写入.js
const fs = require('fs');
let data = fs.readdirSync('./');
data.forEach((item, index) => {
if(Number(item.split('.')[0]) < 10) {
fs.renameSync(item, '0'+item)
}
})
三、path模块(操作路径)
3.1 相关Api
* path.resolve:拼接规范的绝对路径
* path.sep:获取操作系统的路径分隔符
* path.parse:解析路径并返回对象
* path.basename:获取路径的基础名称
* path.dirname:获取路径的目录名
* path.extname:获取路径的拓展名
3.2 示例
const path = require('path');
// __dirname所在文档的绝对路径
console.log(path.resolve(__dirname, 'test.html')); // D:\node-test\test.html
console.log(path.sep); // windows \ linux /
let str = 'D:\\node-test\\test.html';
console.log(path.parse(str)); // { root: 'D:\\' ... }
console.log(path.basename(str)); // text.html
console.log(path.dirname(str)); // D:\node-text
console.log(path.extname(str)); // .html
四、http模块(创建服务器和处理网络通信)
4.1 http模块介绍
- 作用:创建服务器和处理网络通信
- 获取请求报文
- 请求方法:req.method:
- 请求头信息:req.headers
- 获取请求体
<!-- 可通过表单post请求验证 -->
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => console.log(body));
// 方法一
const http = require('http');
const url = require('url');
const server = http.createServer((req, res) => {
console.log(req.url); // /search?id=123
console.log(url.parse(req.url, true).pathname); // /search
console.log(url.parse(req.url, true).query); // { id: 123 }
})
server.listen(9000, () => {
console.log('Server running at http://localhost:9000/')
})
// 方法二
const http = require('http');
const server = http.createServer((req, res) => {
let url = new URL(req.url, 'http://127.0.0.1');
console.log(url.pathname); // /search
console.log(url.searchParams.get('id')); // 123
})
server.listen(9000, () => {
console.log('Server running at http://localhost:9000/')
})
- 设置响应报文
- 设置状态码:res.statusCode = 200
- 设置响应头:res.setHeader(‘Content-Type’, ‘text/html’)
- 写入响应内容:res.write(‘Hello’)
- 结束响应:res.end()
- 注意:
- 服务启动后,更改代码需重启服务才能生效
- http协议默认端口是80
- favicon.ico:属于浏览器自动发送的请求
4.2 http练习-实现网页引入外部资源
html
-css/index.css
-js/index.js
-index.html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="/css/index.css">
</head>
<body>
<div class="content">你好,世界</div>
</body>
<script src="/js/index.js"></script>
</html>
const fs = require('fs');
const http = require('http');
const server = http.createServer((req, res) => {
let { pathname } = new URL(req.url, 'http://127.0.0.1');
// 网站根目录
let root = __dirname + '/html';
// 拼接文件路径 - 重点注意:可以是html,css,js以及图片
let filePath = root + pathname;
fs.readFile(filePath, (err, data) => {
if(err) {
res.statusCode = 500;
res.end('文件读取失败');
return
}
res.end(data)
})
})
server.listen(9000, () => {
console.log('runing http://localhost:9000')
})
- 注意:上述html引入文件建议绝对路径:/css/index.css /js/index.js的样式
五、模块化
5.1 模块化概念
六、相关概念
6.1 计算机相关概念
- 计算机组成:CPU,内存,硬盘等
- 操作系统:
- 概念:一种应用程序,用来管理和调度硬件资源
- 类型:windows linux macOS
- 程序:
- 程序一般保存在硬盘中
- 软件安装就是将程序写入硬盘
- 程序运行会加载进入内存,然后由CPU读取并执行程序
- 进程与线程:
- 进程:程序的一次执行过程
- 线程:一个进程中执行的一个执行流
6.2 命令行介绍
- 常用命令
- 切换盘符:c:,d:
- 切换目录:cd
- 查看目录文件:dir
- 查看所有文件(含子文件):dir /s
- 示例
6.3 Buffer
- 概念:类似于数组的对象,用于表示固定长度的字节序列
- 特点:
- 1.大小固定无法调整,每个元素的大小为一个字节(byte)
- 2.性能好,可以直接对计算机内存进行操作
- 使用场景:
- 文件读写:读取和写入二进制文件(如图片、音频文件等)
- 网络通信:处理 HTTP 请求、TCP/UDP 数据流。
- 存在原因:
- js字符串是基于UTF-16编码的,不适合处理二进制数据,可能会损坏数据
- Buffer是专门为二进制数据设计,文件、图片、音频等都是二进制数据,需要通过Buffer来读取、存储等
6.4 http协议
- http协议:用于在客户端和服务器之间传输数据的通信协议
- http版本号:1.0/1.1/2/3
- 报文:HTTP通信的基本单位(可通过fiddler软件拦截查看)
- 请求报文
- 请求行:方法 + URL路径 + HTTP版本 示例:GET https://www.baidu.com/ HTTP/1.1
- 请求头:
- Host: www.example.com(目标域名)
- User-Agent: Chrome/…(客户端信息)
- Accept: text/html(可接受的响应类型)
- Content-Type: application/json(请求体的数据类型)
- Cookie: user=abc(身份凭证)
- 请求体:
- 响应报文:
- 响应行:HTTP版本 + 状态码 + 状态文本 示例:HTTP/1.1 200 OK
- 响应头:
- Content-Type: text/html(响应体的数据类型)
- Content-Length: 1024(响应体大小)
- Cache-Control: max-age=3600(缓存控制)
- 响应体:
- 响应状态码:
- 1xx:信息响应
- 2xx:成功响应
- 3xx:重定向消息
- 4xx:客户端错误响应
- 5xx:服务端错误响应
6.5 URL(统一资源定位符)
- 定义:互联网上资源的唯一地址
- 作用:
- 定位资源:精确指向网页,图片等
- 定义访问方式:通过协议指定如何获取资源(HTTP/HTTPS/FTP)
- 传递参数:通过查询字符串向服务器发送数据
- 组成:https://www.example.com:443/path?query=123#section
- 协议(Scheme):
- 访问资源的规则(如 https://、ftp://)。
- 决定数据传输方式(加密/非加密等)。
- 域名:服务器名称
- 端口:应用程序的数字标识
- 路径:服务器上资源的位置
- 查询参数:传递给服务器的附加数据
- 锚点:指向页面中的特定位置(#section)
- 网页中URL
6.6 mime类型(媒体类型)
- 作用:http服务可以设置响应头content-type来表明响应体的mime类型,浏览器根据类型决定如何处理资源
- 常见的mine类型
- html:text/html
- css :text/css
- js :text/javascript
- jpg :image/jpeg
- json:application/json
- 举例:res.setHeader(‘content-type’, ‘text/html;charset=utf-8’)