• 【前端】NodeJS核心知识点整理


    1.Node.js入门案例

    1.1.什么是Node.js

    在这里插入图片描述

    JS是脚本语言,脚本语言都需要一个解析器才能运行。对于写在HTML页面里的JS,浏览器充当了解析器的角色。而对于需要独立运行的JS,NodeJS就是一个解析器。

    每一种解析器都是一个运行环境,不但允许JS定义各种数据结构,进行各种计算,还允许JS使用运行环境提供的内置对象和方法做一些事情。例如运行在浏览器中的JS的用途是操作DOM,浏览器就提供了document之类的内置对象。而运行在NodeJS中的JS的用途是操作磁盘文件或搭建HTTP服务器,NodeJS就相应提供了fshttp等内置对象。

    在这里插入图片描述

    Node.js是一个调用内置ApI并且基于Chrome V8引擎的js运行环境,之前自己在本地总结了一些零散的只知识点,今天整合一下发出来。

    1.2 Node.js可以做什么
    • 基于 Express 框架(http://www.expressjs.com.cn/),可以快速构建 Web 应用。
    • 基于 Electron 框架(https://electronjs.org/),可以构建跨平台的桌面应用
    • 基于restify框架(http://restify.com/),可以快速构建 API 接口项目
    • 读写和操作数据库、创建实用的命令行工具辅助前端开发
    1.3.Node.js安装

    下载链接:https://nodejs.org/en/

    官方提供两个版本:

    在这里插入图片描述

    • LTS:长期稳定版
    • Current:尝鲜版

    按照官方提供的步骤安装完成后,查看node的版本

    node -v
    
    • 1

    在这里插入图片描述

    1.4.在Node.js中运行JS代码

    (1)准备js代码

    const name = "李祥";
    console.log(name);
    
    • 1
    • 2

    (2)运行js代码

    李祥
    
    • 1

    2.Node.js内置的模块

    2.1.文件系统fs模块

    fs模块:node提供用来操作文件的内置模块,模块里有很多属性和方法,用于处理文件。

    (1)读取文件内容

    // path:路径
    // options:编码格式
    // callback:回调函数
    fs.readFile(path,options,callback)
    
    • 1
    • 2
    • 3
    • 4
    const fs = require('fs');
    fs.readFile('./a.txt','utf-8',(err,data)=>{
        if(err){
            console.log(err);
        }
        console.log(data);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • a.txt文件中的内容:

    在这里插入图片描述

    • 运行结果:
    I am 李祥
    I like 写代码
    
    • 1
    • 2

    (2)写入文件内容

    // path:路径
    // content:写入的内容,注意应是字符串方式
    // callback:回调函数
    fs.writeFile(path,content,callback);
    
    • 1
    • 2
    • 3
    • 4
    const fs = require('fs');
    const content = '写入文件的内容';
    fs.writeFile('./a.txt',content,(err)=>{
        if(err){
            console.log(err);
        }
        console.log('写入成功');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • a.txt文件中的内容:
    写入文件的内容
    
    • 1

    (3)追加文件内容

    // path:路径
    // content:写入内容
    // callback:回调函数
    fs.appendFile(path,content,callback);
    
    • 1
    • 2
    • 3
    • 4
    const fs = require('fs');
    const contentAppend = '追加文件内容';
    fs.appendFile('./a.txt',contentAppend,err=>{
        if(err){
            console.log(err);
        }
        console.log('追加成功');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • a.txt文件中的内容:
    写入文件的内容追加文件内容
    
    • 1

    注意点:

    • readFile只能读取已经存在的文件。
    • writeFile写入内容已经有文件,则创建同名文件,再写入文件。
    • readFile需要在writeFile后面读取,不然出错。
    2.2.路径path模块

    (1)解决node启动相对路径问题

    执行启动node进程时,是以当前终端的路径进行拼接代码中的相对路径。当前路径有出入时,会出现路径拼接错误。

    举个栗子:这段代码,如果我进到当前js文件的路径下进行执行没有问题。

    在这里插入图片描述

    但是,如果我在他的上一层执行这个文件,就会报错。

    在这里插入图片描述

    如何解决这个问题呢,路径前缀加上绝对路径的标识。

    在这里插入图片描述

    在这里插入图片描述

    (2)join方法的用法

    path.join用于路径的拼接

    const fs = require('fs');
    // 路径拼接的方法:path.join()
    const dirPath = path.join(__dirname,'a.txt');
    fs.readFile(dirPath,'utf-8',(err,data)=>{
        if(err){
            console.log(err);
            return;
        }
        console.log(data);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (3)获取文件的路径和扩展名

    const path = require('path');
    
    //获取路径中的最后一部分 path.basename()
    require('path').basename('/test/something') //运行结果:something
    require('path').basename('/test/something.txt') //运行结果:something.txt
    require('path').basename('/test/something.txt', '.txt') //运行结果:something
    
    //获取路径中的目录部分 dirname()
    require('path').dirname('/test/something') // 运行结果:/test
    require('path').dirname('/test/something/file.txt') // 运行结果:/test/something
    
    //获取路径中的扩展名部分 extname()
    require('path').extname('/test/something') // 运行结果:''
    require('path').extname('/test/something/file.txt') // 运行结果:'.txt'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.3.网络http模块

    定义Node.js提供创建web服务器

    (1)初始化一个web服务器

    // 引入http模块
    const http = require('http');
    
    // 创建服务器
    const server = http.createServer();
    
    //监听客户端的请求
    server.on('request',(req,resp)=>{
        const mess = `请求地址:${req.url},请求方法:${req.method}`;
        //解决中文乱码的问题
        resp.setHeader('Content-Type', 'text/html;charset=utf-8');
        //响应的内容和结束本次请求
        resp.end(mess);
    });
    
    //启动服务
    server.listen(3000,()=>{
        console.log('服务运行在:http://127.0.0.1:3000');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (2)根据浏览器访问的url地址不同,返回不同的资源

    //引入http模块
    const http = require('http');
    
    //创建服务器
    const server = http.createServer();
    
    //监听客户端的请求
    server.on('request', (req, res) => {
      //设置默认的返回内容
      let mess = '404 页面请求失败';
      //判断请求的地址
      if (req.url === '/' || req.url === '/home') {
        mess = '

    首页

    '
    ; } else if (req.url === 'about') { mess = '

    关于

    '
    ; } res.setHeader('Content-Type', 'text/html;charset=utf-8'); res.end(mess); }); //启动服务器 server.listen(3000, () => { console.log('服务运行在:http://127.0.0.1:3000'); });
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    2.4.缓冲区Buffer

    Buffer 定义:Buffer 是内存区域,固定大小的内存块,可以将buffer视为数组,每个元素代表一个数据字节,由Node中Buffer类实现。

    Buffer的数据形式:保存在Buffer中的数据是以十六进制的形式展示的,更加简短,但是计算机底层处理的还是二进制数据。

    const buf = Buffer.from('lixiang');
    console.log(buf);
    
    const buf1 = Buffer.from('理想');
    console.log(buf1);
    
    //将字符串转成buffer
    Buffer.from('lixiang');
    
    //创建一个指定大小的buffer
    console.log(Buffer.alloc(10));
    
    //在buffer池中使用原有的buffer,可能含有敏感数据,但是性能会更好
    console.log(Buffer.allocUnsafe(10));
    
    //将buffer转成字符串
    const change = Buffer.from('lixiang');
    change.toString();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 运行结果:
    <Buffer 6c 69 78 69 61 6e 67>
    <Buffer e7 90 86 e6 83 b3>
    <Buffer 00 00 00 00 00 00 00 00 00 00>
    <Buffer 00 00 00 00 00 00 00 00 00 00>
    
    • 1
    • 2
    • 3
    • 4
    2.5.流Stream

    Stream : 是一种以高效的方式处理读/写文件io、网络通信、或任何类型的端到端的信息交换。

    在传统的方式中,读取文件时,会将文件从头到尾读入内存(buffer),然后进行处理。

    使用流,则可以逐个片段地读取并处理。

    const fs = require('fs');
    const path = require('path');
    
    // 创建可读流
    const flowa = fs.createReadStream(path.join(__dirname,'/a.txt'));
    // 创建可写流
    const flowb = fs.createWriteStream(path.join(__dirname,'/b.txt'));
    
    // 通过pipe建立管道流
    flowa.pipe(flowb);
    
    // 监听数据完成流向
    flowa.on('end',()=>{
        console.log('数据流向成功');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.Express框架开发

    3.1.Express框架发起请求

    基于Node.js平台,快速、开发、极简的web开发框架。

    其实就是node npm包管理工具中的第三方包,可以使用express快捷创建服务器。

    其他的node框架koa2。

    (1)发起get请求

    // 创建服务器
    const express = require("express");
    const app = express();
    app.get('/user/info',(req,resp)=>{
      console.log(req.query);
      console.log('查询用户信息');
      const userInfo = {
        id:10001,
        name:'李祥'
      }
      resp.send(userInfo);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 运行结果:
    {
      "id":"100001",
       "name":"李祥"
    }
    
    • 1
    • 2
    • 3
    • 4

    (2)发起post请求

    // 创建服务器
    const express = require("express");
    const app = express();
    app.post('/user/login',(req,resp)=>{
      console.log(req.body);
      console.log('查询用户信息');
      const userInfo = {
        code:200,
        msg:'',
        data:null
      }
      resp.send(userInfo);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 运行结果:
    {
      "code":200,
      "msg":"",
      "data":null
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3.2.Express框架路由

    express中的路由

    前端中的路由 router 一样,在不同的路由页面展示不同的内容

    express中的路由就是不同路径的接口,响应客户端不同的数据

    (1)创建路由模块

    const express = require("express");
    // 创建路由模块
    const router = express.Router();
    
    router.get('/user/info',(req,resp)=>{
      console.log(req.query);
      console.log('查询用户信息');
      const userInfo = {
        id:10001,
        name:'李祥'
      }
      resp.send(userInfo);
    });
    
    router.post('/user/login',(req,resp)=>{
      console.log(req.body);
      console.log('查询用户信息');
      const userInfo = {
        code:200,
        msg:'',
        data:null
      }
      resp.send(userInfo);
    });
    
    module.export = router;
    
    • 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

    (2)使用中间件注册路由模块

    const router = require('./router/user');
    //使用中间件注册路由模块
    app.use(router);
    
    • 1
    • 2
    • 3
    • 运行结果是一样的。
    3.3.全局注册和局部注册

    全局使用,直接用app.use()即可,所有的接口都会走中间件的逻辑

    app.use(middle);
    
    • 1

    局部使用,就在指定的请求上加入中间件即可

    当有多个中间件时,传入一个数组即可,一个就传入当前的这个中间件名称就可以了

    app.get('/user/info',[middleA,middleB],(req,resp)=>{});
    
    • 1

    (1)中间件的定义

    // 声明一个中间件
    const middle = (req, res, next) => {
      console.log('一个中间件');
      /**
       * 逻辑处理
       */
    
      //逻辑处理完成后,必须调用next()将程序交给下个中间件或者路由,否则程序停止
      next();
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (2)全局中间件注册

    const express = require('express');
    const app = express();
    
    const middleA = (req,resp,next)=>{
      console.log('中间件处理middleA');
      next();
    }
    app.use(middleA);
    app.get('/user/info',(req,resp)=>{
      console.log(req.query);
      console.log('查询用户信息');
      const userInfo = {
        id:10001,
        name:'李祥'
      }
      resp.send(userInfo);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 运行结果:
    控制台打印:
    中间件处理middleA
    
    • 1
    • 2

    (3)局部中间件注册

    app.get('/user/info',middleA,(req,resp)=>{
      console.log(req.query);
      console.log('查询用户信息');
      const userInfo = {
        id:10001,
        name:'李祥'
      }
      resp.send(userInfo);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    3.4.五种类型中间件

    (1)内置中间件

    • express内置的中间件4.16.0+
    • express.json()解析json格式请求提数据
    • express.urlencoded()解析url-encoded格式请求体数据
    app.use(express.json());
    app.use(express.urlencoded());
    
    • 1
    • 2

    (2)应用级别中间件

    • 全局中间件和局部中间件直接绑定在app的实例上,就叫应用级别中间件
    //全局中间件
    app.use(middleware);
    //局部中间件
    app.get("/user/info", middleware, () => {});
    
    • 1
    • 2
    • 3
    • 4

    (3)路由级别中间件

    • 中间件绑定在路由router实例上
    router.use(middleware);
    
    • 1

    (4)错误级别中间件

    • 在全局项目中捕获异常错误,防止项目报错异常崩溃
    app.use((err, req, resp) => {
      resp.send(err.message);
    });
    
    • 1
    • 2
    • 3

    (5)第三方中间件

    • body-parser中间件,解析请求体json、url-encoded数据
    • 下载:cnpm i body-parser -S
    const bodyParser = require('body-parser');
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extend:false}));
    
    • 1
    • 2
    • 3

    OK,结束啦,记得给博主三连哦!!!
    在这里插入图片描述

  • 相关阅读:
    K8s ingress-nginx根据请求目录不同将请求转发到不同应用
    Superset 二次开发之PostgreSQL 数据库DDL使用
    一步步教你使用GDB调试程序:从入门到精通的全面指南
    10:00面试,10:06就出来了,问的问题有点变态。。。
    2022年全球最具技术实力的的智能合约安全审计公司推荐
    前后端(react+springboot)服务器部署
    数据结构与算法:排序专题
    单链表的定义、初始化、建立、插入、删除
    【机器学习】集成学习:使用scikitLearn中的BaggingClassifier实现bagging和pasting策略
    【时间序列】时间序列预测基本方法:移动平均(SMA,EMA,WMA)
  • 原文地址:https://blog.csdn.net/weixin_47533244/article/details/134087832