
目录1、BufferBuffer的创建Buffer的操作2、fs模块2.1 写入文件2.1.1 writeFile写入2.1.2 追加写入2.1.3 流式写入2.2 读取文件2.2.1 readFile读取2.2.2 流式读取2.3 文件复制2.4 文件重命名和移动2.5 文件删除2.6 文件夹操作2.7 查看资源状态2.8 路径2.9 批量重命名2.10 path模块3、HTTP模块3.1 HTTP协议3.2 HTTP3.2.1 创建HTTP服务端3.2.2 获取HTTP请求报文3.2.3 设置HTTP响应报文3.3 网页资源加载基本过程3.4 网页中的URL3.4.1 绝对路径项目中常用3.4.2 相对路径学习中常用不安全3.5 设置资源类型mime类型3.6 get和post请求应用场景和区别注意nodejs中不能使用DOM和BOM顶级对象是globalglobalThis指向顶级对象1、Buffer一段固定长度的内存空间用来处理二进制数据特点Buffer 大小固定且无法调整 、性能较好可以直接对计算机内存进行操作 、每个元素的大小为1字节byteBuffer的创建// alloc // let buf Buffer.alloc(10); // 创建一个10字节的Buffer // console.log(buf) // 把每一位归零 // allocUnsafe // let buf Buffer.allocUnsafe(10); // console.log(buf) // 不归零比alloc快但是不安全内存可以复用可能有之前程序遗留的数据 // from // let buf Buffer.from(hello); //Unicode码表完全兼容ASCll码表 // let buf1 Buffer.from([105, 108, 111, 108, 101, 121, 111, 117]) // console.log(buf1)Buffer的操作// buffer与字符串的转换 let buf1 Buffer.from([105, 108, 111, 108, 101, 121, 111, 117]) // console.log(buf1.toString()) // 默认采用utf-8 编码方式 buf1[0] 97 // console.log(buf1.toString()) // buffer元素的读写 let buf Buffer.from(hello) // console.log(buf[0]); // 获取第一个元素 得到的是十进制的数字 // console.log(buf[0].toString(2)) // 转换成二进制 // 溢出 // let buf2 Buffer.from(hello) // buf2[0] 361 // 8个二进制位265361 3610001 0110 1001 高于8位会舍弃高位的数字0110 1001 // console.log(buf2) // 中文 let buf2 Buffer.from(你好) // utf-8的字符一个字符占3个字节 console.log(buf2)2、fs模块2.1 写入文件场景下载文件、安装软件、保存程序日志egGit、编辑器保存文件、视频录制...当需要持久化的保存数据时我们应该想到写入文件2.1.1 writeFile写入// 1. 导入fs模块 const fs require(fs) // writeFile(file文件名, data写入文件的内容, option(可选), callback) 返回值void // writeFile 异步写入 fs.writeFile(./111.txt, 111, err { // err成功null 失败错误对象 if (err) { console.log(失败) return } console.log(成功) }) // writeFileSync 同步写入 fs.writeFileSync(./222.txt, 222)2.1.2 追加写入// appendFile(file文件名, data写入文件的内容, option(可选), callback) 返回值undefined fs.appendFile(./111.txt, 23456, err { if (err) { console.log(失败) return } console.log(成功) }) // appendFileSync 异步追加写入 返回值undefined fs.appendFileSync(./222.txt,3456) // \r\n 换行 fs.appendFileSync(./222.txt,\r\n3456) // writeFile 实现追加写入 fs.writeFile(./111.txt, 111, { flag: a }, err { // err成功null 失败错误对象 if (err) { console.log(失败) return } console.log(成功) })应用场景需要持续的往文件中写内容eg日志2.1.3 流式写入// 1. 导入fs模块 const fs require(fs) // 创建写入流对象 let ws fs.createWriteStream(./ws.txt) ws.write(11111\r\n) ws.write(22222\r\n) ws.write(33333\r\n) // 关闭通道 ws.end()当脚本执行完毕后资源会回收通道会被断开内容已经写入完毕因此end加不加都可流式写入适用于大文件写入或者频繁写入writeFile适合于写入频率较低的场景2.2 读取文件场景电脑开机、程序运行、编辑器打开文件、查看图片、播放视频、播放音乐、Git查看日志、上传文件、查看聊天记录2.2.1 readFile读取// 1. 导入fs模块 const fs require(fs) // readFile(path, option(可选),callback) fs.readFile(./111.txt, (err, data) { if (err) { console.log(失败) return } console.log(data.toString()) })2.2.2 流式读取// 1. 导入fs模块 const fs require(fs) // 创建读取流对象 let rs fs.createReadStream(./111.txt) // 绑定 data 事件 一块一块的读当从文件中读一块就调用一次回调 rs.on(data, chunk { console.log(chunk) console.log(chunk.length) // 如果是一个视频文件toString得不到想要的结果 console.log(chunk.toString()) }) rs.on(end, () { console.log(读取完成); })2.3 文件复制// 1. 导入fs模块 const fs require(fs) const process require(process) // 方式一 readFile 把所有的文件读取到内存中再写入文件 let data fs.readFileSync(./111.txt) fs.writeFileSync(./222.txt, data) // 获取程序的内存占用量 console.log(process.memoryUsage()) // 方式二 流式操作 更好一块一块的读取但是读取的速度比写入的速度快 const rs fs.createReadStream(./111.txt) const ws fs.createWriteStream(./333.txt) // rs.on(data, chunk { // ws.write(chunk) // }) // rs.on(end, () { // console.log(process.memoryUsage()) // }) // 快速复制 rs.pipe(ws)2.4 文件重命名和移动// 1. 导入fs模块 const fs require(fs) // 重命名 // rename(old path,new path,callback) renameSync 同步 fs.rename(./111.txt, ./555.txt, err { if (err) { console.log(失败) return } console.log(成功) }) // 文件的移动 fs.rename(./222.txt, ../test/222.txt, err { if (err) { console.log(失败) return } console.log(成功) })2.5 文件删除// 1. 导入fs模块 const fs require(fs) // 方式一unlink 同步unlinkSync // fs.unlink(./555.txt, err { // if (err) { // console.log(失败) // return // } // console.log(成功) // }) // 方式二rm 同步rmSync fs.rm(./ws.txt, err { if (err) { console.log(失败) return } console.log(成功) })2.6 文件夹操作// 1. 导入fs模块 const fs require(fs) // 创建文件夹 // // mkdir(path(,option),callback) // fs.mkdir(./html/, err { // if (err) { // console.log(失败) // return // } // console.log(成功) // }) // // 递归创建 // fs.mkdir(./a/b/c, { recursive: true }, err { // if (err) { // console.log(失败) // return // } // console.log(成功) // }) // // 读取文件夹 // fs.readdir(../test, { recursive: true }, (err, data) { // if (err) { // console.log(失败) // return // } // console.log(data) // }) // 删除文件夹 // fs.rmdir(./html, err { // if (err) { // console.log(失败) // return // } // console.log(成功) // }) // 递归删除 // 不建议使用 // fs.rmdir(./a, { recursive: true }, err { // if (err) { // console.log(失败) // return // } // console.log(成功) // }) // 建议使用 fs.rm(./a, { recursive: true }, err { if (err) { console.log(失败) return } console.log(成功) })2.7 查看资源状态// 1. 导入fs模块 const fs require(fs) fs.stat(../test/222.txt, (err, data) { if (err) { console.log(失败) return } console.log(data) })2.8 路径// 1. 导入fs模块 const fs require(fs) const path require(path) // 相对路径 fs.writeFileSync(./index.html, 111) fs.writeFileSync(/index.html, 111) fs.writeFileSync(../index.html, 111) // 绝对路径 C盘不可以因为没有权限 fs.writeFileSync(D:/index.html,111) // 相对路径参照物命令行的工作目录 // __dirname保存的是所在文件的所在目录的绝对路径 console.log(__dirname) fs.writeFileSync(__dirname D:/index.html, 111)2.9 批量重命名// 1. 导入fs模块 const fs require(fs) const files fs.readdirSync(./test) console.log(files) files.forEach(item { let data item.split(-) let [num, name] data if (num 10) { num 0 num } let newName num - name fs.renameSync(./test${item}, ./test/${newName}) })2.10 path模块const pathrequire(path) // resolve(绝对路径, 相对路径) path.resolve(__dirname, ./index.html) path.resolve(__dirname, index.html) // sep 分隔符 当前操作系统的路径分隔符 console.log(path.sep) console.log(__filename) // 文件的绝对路径 let str D:\\Nodejs\\index.html // console.log(path.parse(str)) // console.log(path.basename(str)) // console.log(path.dirname(str)) // console.log(path.extname(str))3、HTTP模块IP的作用标识网络中的设备实现设备间通信端口的作用实现不同主机访问相同应用HTTP服务在哪个文件夹中寻找静态资源哪个文件夹就叫静态资源目录也就是网站根目录3.1 HTTP协议HTTP协议请求行请求头空行请求体请求行请求方法请求的URLHTTP的版本号请求方法GET用于获取数据 POST用于新增数据PUT/PATCH更新数据 DELET删除数据URL统一资源定位符URL协议名 :// 主机名端口号路径查询字符串键值对请求头由一系列的键值对组成主要记录浏览器的相关信息、交互的行为、请求体相关的信息请求体和查询字符串格式一样响应报文响应行响应头空行响应体响应头HTTP版本号响应状态码响应状态的描述记录与服务器相关的信息和响应体相关的信息响应状态码响应状态描述响应体常见格式HTML、CSS、JavaScript、图片、视频、JSON3.2 HTTP响应内容解决中文乱码问题response.setHeader(content-type, text/html;charsetutf-8)HTTP协议默认端口是80。HTTP服务开发常用端口有3000808080909000等HTTPS协议默认端口是443。可以使用资源监视器查看端口占用情况3.2.1 创建HTTP服务端// 1. 导入http模块 const http require(http) // 2. 创建服务对象 // 第一个参数是封装请求报文的对象 // 第二个参数是封装响应报文的对象 // 回调函数执行时机当服务接收到http请求时 const server http.createServer((request, Response) { Response.end(Hello HTTP) // 设置响应体并结束这个响应 }) // 3. 监听端口启动服务 // 回调函数执行时机当服务启动成功时 // 浏览器可以发送HTTP请求 9000端口 // 本机(回环地址)127.0.0.1 server.listen(9000, () { console.log(Server Success) })3.2.2 获取HTTP请求报文获取请求行和请求头// 1. 导入http模块 const http require(http) const server http.createServer((request, response) { response.setHeader(content-type, text/html;charsetutf-8) console.log(request.method) console.log(request.url) //只包含 url 中的路径和查询字符串 console.log(request.httpVersion) //获取http协议的版本号 console.log(request.headers) //获取请求头 console.log(request.headers.host) //获取端口号 response.end(HTTP) }) server.listen(9000, () { console.log(Server Success) })获取请求体这个方法了解即可// 1. 导入http模块 const http require(http) const server http.createServer((request, response) { let body request.on(data, chunk { console.log(chunk) body chunk }) request.on(end, () { console.log(body) response.end(hello Http) }) }) server.listen(9000, () { console.log(Server Success) })获取请求路径和查询字符串方式一// 1. 导入http模块 const http require(http) const url require(url) const server http.createServer((request, response) { // console.log(request.url) // let res url.parse(request.url) let pathname url.parse(request.url).pathname let query url.parse(request.url, true).query.keyword console.log(pathname) console.log(query) response.end(url) }) server.listen(9000, () { console.log(Server Success) })方式二// 1. 导入http模块 const http require(http) const server http.createServer((request, response) { // 实例化 URL 的对象 // let url new URL(http://www.xxx.com/s?a100b10) // let url new URL(/s?a100b10, http://127.0.0.1:9000) let url new URL(request.url, http://127.0.0.1:9000) // console.log(url) console.log(url.pathname) // url.search是一个字符串我们用起来不方便 // searchParams是一个对象 使用get方法获取 console.log(url.searchParams.get(keyword)) response.end(url) }) server.listen(9000, () { console.log(Server Success) })3.2.3 设置HTTP响应报文const http require(http) const server http.createServer((request, response) { // 设置响应状态码 response.statusCode 200 // 响应状态的描述 response.statusMessage success // 响应头 response.setHeader(content-type, text/html;charsetutf-8) // response.setHeader(myHeader, test test) // 设置多个同名响应头 // response.setHeader(test, [a, b, c]) // 响应体 一般使用write时最后在end中就不设置响应体了write可以多次复用设置响应体 response.write(response) response.write(response) response.write(response) response.write(response) response.end() // response.end(end...) }) server.listen(9000, () { console.log(Server Success) })3.3 网页资源加载基本过程首先发送http请求获取网页的html内容当看到link标签引入的css文件时发送http请求获取css内容浏览器使用css中的样式去控制页面当中的元素样式在html中遇到img标签需要呈现一个外部的图片资源向服务器发送请求在html中遇到script标签有src属性时继续向服务器发送请求获取js资源完成整个页面的加载。发送请求是一个异步的过程并不是发一个请求等待响应之后才发下一个请求3.4 网页中的URL两类相对路径和绝对路径3.4.1 绝对路径项目中常用3.4.2 相对路径学习中常用不安全相对路径发送请求时需要与当前页面URL路径进行计算得到完整的URL后再发送请求eg当前网页url为http://www.atguigu.com/course/h5.html3.5 设置资源类型mime类型媒体类型通常称为 Multipurpose Internet Mail Extensions或MIME类型 是一种标准用来表示文档、文件或字节流的性质和格式。mime类型结构[type]/[subType]例如text/html text/css image/jpeg image/png application/jsonHTTP 服务可以设置响应头Content-Type来表明响应体的MIME类型浏览器会根据该类型决定如何处理资源下面是常见文件对应的mime类型html:text/html,css:text/css,js:text/javascript,png:image/png,jpg:image/jpeg,gif:image/gif,mp4:video/mp4,mp3:audio/mpeg,json:application/json对于未知的资源类型可以选择application/octet-stream类型浏览器在遇到该类型的响应时会对响应体内容进行独立存储也就是我们常见的下载效果const http require(http) const fs require(fs) const path require(path) const mimes { html: text/html, css: text/css, js: text/javascript, png: image/png, jpg: image/jpeg, gif: image/gif, mp4: video/mp4, mp3: audio/mpeg, json: application/json } const server http.createServer((request, response) { let { pathname } new URL(request.url, http://127.0.0.1) let root __dirname /page let filePath root pathname fs.readFile(filePath, (err, data) { if (err) { response.setHeader(content-type, text/html;charsetutf-8) response.statusCode 500 response.end(no success) return; } // 获取文件的后缀名 let ext path.extname(filePath).slice(1) // console.log(ext) let type mimes[ext] if (type) { // 解决乱码问题 比html中的meta优先级高 response.setHeader(content-type, type ;charsetutf-8) } else { response.setHeader(content-type, application/octet-stream) } response.end(data) }) }) server.listen(9000, () { console.log(serve) })3.6 get和post请求应用场景和区别GET请求的情况在地址栏直接输入url访问点击a链接link标签引入cssscript标签引入jsimg标签引入图片form标签中的method为get不区分大小写ajax中的get请求POST请求的情况form标签中的method为post不区分大小写AJAX的post请求区别作用GET主要用来获取数据POST主要用来提交数据参数位置GET带参数请求是将参数缀到URL之后在地址栏中输入url访问网站就是GET请求POST 带参数请求是将参数放到请求体中安全性POST请求相对GET安全一些因为在浏览器中参数会暴露在地址栏GET请求大小有限制一般为2K而POST请求则没有大小限制