nodejs全栈开发课程笔记

这篇博客是关于Node.js全栈开发的课程笔记,涵盖从安装到实战的全过程。讲解了Node.js的基础知识,如npm、nodemon和nvm的使用,接着介绍了Web应用基础,特别是Express框架的应用,包括路由和中间件的使用。此外,还深入探讨了Sequelize ORM与MySQL的结合,以及如何创建Todo实例模型并进行数据库操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@nodejs全栈开发课程笔记

✪ nodejs第一个程序

编写一段js来读取CPU,内存的脚本

demo.js
读取cpu代码片`.

// 读取系统的CPU信息
const os = require('os');
const cups = os.cups(); //获取当前系统的cpu的数量
console.log(cups.length);

//获取内存的信息
const total = os.totalmen(); //bytes
console.log(total/1024/1024/1024); //GB
const free = os.freemen();
console.log(free/1024/1024/1024) //GB

Web服务常用代码片段

// web服务
// ajax-->api-->web server(nodejs)
const http = require('http');
const server = http.createServer((req,res)=>{
  res.end('helle')
})
//服务器监听,端口3000,监听本地127.0.0.1
server.listen(3000,'127.0.0.1',()=>{
  console.log('服务启动成功')
})

在命令运行

$ node src/demo.js

✪ Nodejs和npm介绍

在这里插入图片描述

✪ nodemon介绍

配置nodemon
1、npm i nodemon -D
2、修改 package.json 中的启动命令


"scripts":{
  "start":"nodemon src/app.js",
  "start:node":"node src/app.js"
}

3、通过增加 nodemon.js 配置文件 指定特殊 watch 的文件
根目录添加 nodemon.json

{
  "watch":["./src/**/*.js"]
}

4、通过添加 DEBUG=* 查看运行细节


"scripts":{
  "start":"DEBUG=* nodemon src/app.js"
}

✪ 使用nrm和nvm介绍

1、配置nrm

npm i nrm -g

2、常用命令

nrm ls  //查看内置元
nrm -h //操作帮助
nrm current  //查看当前源
nrm use 

有些公司可以自己做自己的源,由内部人员调用使用。

3、使用nvm 管理nodejs 版本

nvm ls-remote --lts  //查看远程nodejs的版本列表
nvm i v10.14.1 //安装需要的版本
nvm use v8.9.0  //制定使用当前使用的版本
nvm ls //查看本机现在有的版本
nvm alias default v8.9.0 //默认使用的版本

WEB应用基础

web应用
前端
ajax,ws,—>服务器(web应用) —>缓存/数据库

express

接受 req,处理 res

express·:node 中的一种应用框架

1、配置方法

npm i express -S

2、基础实例

app.js

const express = require('express');

// 是一个express实例
const app = express();

app.use((req,res)=>{
  res.json({
     name:"詹胜男"
  })
})

app.listen(3000,()=>{
   console.log("server 启动成功")
})

3、使用get,post的接口方式查看

const express = require('express');

// 是一个express实例
const app = express();

app.get('/name',(req,res)=>{
  res.send('tom')
})

app.post('/name',(req,res)=>{
  res.send('tom post')
})

app.listen(3000,()=>{
   console.log("server 启动成功")
})

4、使用get,post 结合url参数的形式

const express = require('express');

// 是一个express实例
const app = express();

app.get('/name/:age',(req,res)=>{
  let {age} = req.params; //接受参数
  res.json({
     name:"tom",
     age
  })
})
app.listen(3000,()=>{
   console.log("server 启动成功")
})

配图

✪ Route介绍和使用

1、route是什么

web服务 如何处理一个 请求

url → 网络 → dns解析 → 目标服务器

1、如何响应这个请求 → 路由 //规则

  • 1、通过 请求的 方法类型 来区分
    • 1、get
    • 2、post
    • 3、put
    • 4、delete
    • 5、其他
app.get('/demo',(req,res)=>{
})
app.post('/demo',(req,res)=>{
})
  • 2、通过 url——路径
    eg: www.baidu.com/a/c/a.html
    • 1、基础知识,通过不同的路由名称
app.get('/user/byname',(req,res)=>{
})
app.get('/user/byid',(req,res)=>{
})
  • 2、无论通过什么请求方式,都可以得到响应
app.all('/demo',(req,res)=>{
   res.json({
      message:'demo',
      method:req.method  //查看请求的方式
   })
})
  • 3、无论客户端使用任何的 url,我们的服务都可以响应 (使用场景:日志)
app.all('*',(req,res)=>{
   res.json({
      message:'demo',
      method:req.method,  //查看请求的方式
      url:req.path //路径
   })
})
  • 4、app.use — 使用中间件
    建议使用场景,中间件注册时候使用。
app.use('/demo',(req,res)=>{
   res.json({
      message:'demo',
      method:req.method  //查看请求的方式
   })
})
app.use((req,res)=>{
   res.json({
      message:'demo',
      method:req.method,  //查看请求的方式
      url:req.path //路径
   })
})
  • 5、如何做路由的拆分

    eg.一个多功能的商城,有用户(meber)、商品(sku)、订单(order)

   使用 express.Router

方式:
1、在src目录下面新建系列中间件js文件,例如:member.router.js、sku.router.js、order.router.js
member.router.js 代码片段

const express = require('express');
const router = express.Router();
// 便可直接使用需要的路由方法,以下为打比方
router.get('/user/byname',(req,res)=>{...})
router.post('/user/byname',(req,res)=>{...})
router.all('*',(req,res)=>{...})
router.use('/user/byname',(req,res)=>{...})
router.use((req,res)=>{...})

//具体事例
router.get('/list',(req,res)=>{
  res.json({
    list:[
      {
       id:001,
       name:'李四'
       }
    ]
  })
})

module.exports = router; //将路由暴露出去

2、在app.js文件注册路由

...
const app = express();

//注册路由
const memberRouter = require('./member.router');
app.use(memberRouter)

同理,在src文件夹下面,建立 sku.router.js、order.router.js
再在app.js中注册,注意,多个路由中避免重复命名的list,要在注册路由是添加二级路径区分。
app.js代码片段

...
//注册路由
const memberRouter = require('./member.router');
const skuRouter = require('./sku.router');
app.use('/member',memberRouter)
app.use('/sku',skuRouter )

postman访问地址分别为:
http://127.0.0.1/member/list
http://127.0.0.1/sku/list

✪ 中间件介绍与使用

一、中间件完整的结构

1、是一个函数
2、支持的入参有err、req、res、next → 他们可以是function

例如:

function demo_middleware(err,req,res,next){
    //功能
    // 1、处理异常
    // 2、处理下业务功能,然后转交控制权——next
    // 3、响应请求——结束请求 ,即为:当做路由的处理函数。或者说,路由是中间件的一种    
}

例如,在请求前检查是否有参数传入。

  
  // 校验功能函数
  function valid_name_middleware(req,res,next){
    let {name} = req.query;
    if(!name || name.length){
      res.json({
      message: "缺少name参数"    //不满足要求,提示。
      })
    }else{
        next() //满足不为空,爱怎么着下一步就怎么走
    }
  }
  
  // 检查所有访问请求是否都满足“校验功能函数”的条件 
  app.all('*',valid_name_middleware)   //顺序执行的拦路虎

  // 通过拦路虎,继续往下执行其他函数
  ...

测试:
不通过 = http://127.0.0.1:3000/test?name=’’
通过 = http://127.0.0.1:3000/test?name=112

二、中间件分类

1、app 级别的使用

1。 注册的时候,一定是最顶的
2。通过app.use,将api加载进来

例如:

....
//加载自定义的中间件
function log_middleware(req,res,next){
  console.log('请求来了');
  next();
}
app.use(log_middleware);

// 加载系统中已有中间件,例如一个静态页面 express.static 中间件
// 直接写 app.use
app.use(express.static('staticfile',{
}))
// 新建一个 staticfile 文件夹,里面新建一个 index.html 的静态页面
// 浏览器直接输入 http://1278.0.0.1:3000/index.html 就可以访问了

// 注意不能写为 http://1278.0.0.1:3000/index 除非补充一个拓展说明,如下
app.use(express.static('staticfile',{
  extensions:['html','htm']
}))
...

// 拓展学习可以有 express.json、express.urlencoded
// 具体可查看 express官网的guid

2、router 级别

1、基础认识

首先在 src 文件夹下,新建 router 文件夹,再在router 文件夹下新建 user_router.js文件
user_router.js代码片段

const express = require('express');
const router = express.Router(); //路由对象

router.get('/demo',(req,res)=>{
 res.json({
   message:'from router demo' 
 })
})

module.exports = router;

app.js 引入路由

//注册路由
const userRouter = require('./router/user_router');
app.use('/user',userRouter)
2、路由级别加入“加入执行函数”

路由级别的也可以有处理函数。可在 user_router.js 文件中,加入执行函数,
例如

const express = require('express');
const router = express.Router(); //路由对象

/// 本节知识点新增代码
router.use(function(req,res,next){
   console.log('log from router');
   next();
})

router.get('/demo',(req,res)=>{
 res.json({
   message:'from router demo' 
 })
})

module.exports = router;
3、路由级别,路由内部使用的中间件函数

user_router.js

router.get('/demo',[/** middleware 链式的 **/](req,res)=>{
 res.json({
   message:'from router demo' 
 })
})
router.get('/demo',[functionA,functionB...](req,res)=>{
 res.json({
   message:'from router demo' 
 })
})

实例,校验路由传递过来的name、password:

http://127.0.0.1:3000/user?name=tom"&password=123"

user_router.js


function vlaid_login_params(req,res,next){
   //初始化参数名
   let {name,password} = req.query;
   if(!name || !password){
    res.json({
     message:"参数 校验失败"
    })
   }else{
      req.formdata = {
       name,
       password
      }
      next();
   }
}

router.get('/demo',[vlaid_login_params](req,res)=>{
 let {formdata} = req;
 res.json({
   formdata,
   message:'from router demo' 
 })
})

3、异常处理

也可以是属于app级别、router级别,看划分的曾经和想抛出异常的地方。

一、异常捕获

制造一个异常代码,由express框架将异常将其捕获,往外抛出

app.get('/demo',(req,res)=>{
 res.json({
   message   //异常代码,没有定义参数
 })
})

捕获异常

app.get('/demo',(req,res)=>{
 
 //捕获异常
 throw new Error('测试异常功能')
 
 res.json({
   message   //异常代码,没有定义参数
 })
})

二、Express 内置异常处理

定义一个异常处理的中间件

function error_handler_middleware(err,req,res,next){
 if(err){
   res.status(500)
   .json({
      message:'服务器异常'
   })
 }else{
   next()
 }
}

app.use(error_handler_middleware)

针对404的异常处理

在express框架中,404不属于异常,虽然他提示是error,但是没有做处理,因此我们可以专门定义一个针对404的中间件,提示“api不存在”,这个中间件的特点在于,没有 error 参数。

function not_found_handler_middleware(req,res,next){
   res.json({
      message:'api不存在'
   })
}

app.use(not_found_handler_middleware)

三、自定义异常处理

function demo_middleware(req,res,next){
 try {
   // do something
 }catch (error){
   //抛出异常说明
 }
}

✪ Mysql介绍与安装

安装包在百度云盘
1、mysql – 结构化数据库,中的一种
2、mysql – 服务, 提供了数据存放的服务
|——数据库:划分的存储区域
|——table:
|—— 对象数组
|—— js对象数组
[
{
id:1,
name:‘计算机编程’
},
{
id:2,
name:‘C++’
}
]

✪ Sequelize介绍和使用

1、什么是ORM

对象模型数据库,将数据中的表,用对象的方式输出出来,通过js读取出来

2、Sequelize 作用

安装与初始化

cnpm i sequelize sequelize-cli mysql2 -S
npx sequelize-cli init

为什么要装mysql2,因为以下操作路径:

node-application - ORM(sequlize) --> 驱动(node-mysql) --> mysql db

当提示 npm WARN XXX@XXX no description时,添加"private": true, 即可。
在这里插入图片描述

3、在nodejs应用中集成sequelize

新建表

npx sequelize-cli model:generate --name User --attributes name:string

将表加入数据库

npx sequelize-cli db:migrate -env=development

新建可以在前端录入数据的函数

//使用模型对象
const models = require('../models');

app.get('/create',async (req,res)=>{
   let {name}  =  req.query;
   // promise user -->sequlize 对象
   let user = await models.User.create({
      name
   })
})

Todo实例模型

初始化数据库

1.创建一个数据库

2.使用sequlize cli 初始化 项目的数据库配置信息

npx sequlize-cli init 先新建一个db文件夹,再做初始化

3.生成模型文件

1.migrate 文件夹
2.model 文件

npx sequelize-cli model:generate --name Todo --attributes name:string,deadline:date,content:string

4.持久化,模型对应的【数据库表】

npx sequelize-cli db:migrate -env=development

注意,去掉不想要自动声明的 createdate,updatedate。
timestamps:false // 不让他自动创建 记录更新时间

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Todo = sequelize.define('Todo', {
    name: DataTypes.STRING,
    deadline: DataTypes.DATE,
    content: DataTypes.STRING
  }, {
  	timestamps:false  // 不让他自动创建 记录更新时间
  });
  Todo.associate = function(models) {
    // associations can be defined here
  };
  return Todo;
};

API里面具体使用ORM模型

安装body-parser

cnpm i body-parser -S
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(express.json());
// for parsing application/xwww-form-urlencoded
app.use(express.urlencoded());
// for parsing application/xwww-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true}))

//使用模型对象,因为sequlize安装在了一个db文件夹,所以记得加上../db/
const models = require('../db/models'); 

// 1.所有的错误,http status =500
/* 查询任务列表 */
app.get('/list/:status/:page',async (req,res,next)=>{
	res.json({
		list:[]
	})
})
/*  创建 一个 todo  测试用
app.post('/create',async (req,res,next)=>{
   let {name,deadline,content}  =  req.body;
   res.json({
   	todo:{},
   	name,
   	deadline,
   	content
   })
})
*/
/*  创建 一个 todo  真实使用model对象时*/
app.post('/create',async (req,res,next)=>{
   try{
	   let {name,deadline,content}  =  req.body;
	   let todo = await models.Todo.create({
		   	   name,
		   	   deadline,
		   	   content
		})
	   res.json({
	   	todo,
	   	message:"创建成功"
	   })
    }catch (err){ 
      next(err)
    }
})

在这里插入图片描述

/*  修改 一个 todo  测试用
app.post('/update',async (req,res,next)=>{
   let {name,deadline,content,id}  =  req.body;

   res.json({
   	todo:{},
   	name,
   	deadline,
   	content,
   	id
   })
})
*/
app.post('/update',async (req,res,next)=>{
 try{
   let {name,deadline,content,id}  =  req.body;
   let todo = await models.Todo.findOne({
      where:{
        id
      }
   })
   //上一步执行查找以后,接着判断是否找到了todo
   if(todo){
      // 执行更新功能,因为todo是上面let已经定义的models对象,所以直接使用即可
      todo = await todo.update({
        name,
        deadline,
        content
      })
   }
   res.json({
   	todo
   })
  }catch (err){
     next(err)
  }
})


/*  修改 一个 todo, 删除 测试用
app.post('/update_status',async (req,res,next)=>{
   let {id,status}  =  req.body;

   res.json({
   	todo:{},
   	id,
   	status
   })
})
*/

/*  修改 一个 todo, 删除 */
app.post('/update_status',async (req,res,next)=>{
  try{
   let {name,deadline,content,id}  =  req.body;
   let todo = await models.Todo.findOne({
      where:{
        id
      }
   })
   //上一步执行查找以后,接着判断是否找到了todo.,多了一个判断状态是否更新
   if(todo && status!=todo.status){
      // 执行更新功能,因为todo是上面let已经定义的models对象,所以直接使用即可
      todo = await todo.update({
        status
      })
   }
   res.json({
   	todo
   })
  }catch (err){
     next(err)
  }
})

app.get('/list/:status/:page',async (req,res,next)=>{
    let {status,page} = req.params;
    let limit = 10;
    let offset = (page-1)*limit;
    let where = {}
    // 1.状态 1:表示待办,2:完成,3:删除,-1:全部
    // 2.分页的处理
        if(status != -1){
   where.status = status;
}
    let list = await models.Todo.findAndCountAll({
    where,
offset,
limit
})
	res.json({
		list,
		message:"列表查询成功"
	})
})

app.get('/detail/:id',async (req,res)=>{
	let {id} = req.params;
	let user = await models.User.findOne({
		where:{
			id
		}
	})
	res.json({
		user
	})
})


app.use((err,req,res,next)=>{
	if(err){
		res.status(500).json({
			message:err.message
		})
	}
})

app.listen(3000,()=>{
   console.log("server 启动成功")
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值