【老板要我啥都会】|前端升全栈之项目使用express重构项目(下篇)

news/2024/5/17 0:03:21/文章来源:https://blog.csdn.net/Lushengshi/article/details/127161821

前言

承接上一篇文章,《前端升全栈之项目使用express重构项目(上篇)》,我们继续讲解下一篇的项目使用express重构项目完整的下一篇(主要是国庆,需要放松,所以该文章分为上下篇,请大家读友谅解一下!),好了,我们马上进入我们今天的正题!!!

目录

前言

1.express开发项目

2.express处理session

3.session链接redis

4.登录中间件

5.开发路由 

6.Morgan 

7.中间件原理 

8.中间件原理-代码实现 


1.express开发项目

express开发接口:

  1. 初始化接口,之前的部分代码可以复用;
  2. 开发路由,并可以实现登录功能;
  3. 记录日志;

初始化环境:

  1. 安装插件mysql xss;
  2. mysql control resModel 相关代码可以复用;
  3. 初始化路由; 

这个时候我们就可以去把一些自己带有的不用的注释,安装一下我们的mysql和xss.新建一个db文件夹,新建一个mysql.js,将其中的内容拷贝过去,在新建一个conf文件夹,下面建一个db.js,也可以拷贝。这就是数据库先关的。在接下来拷贝controller、model文件夹过去,新建一个utils文件夹,下面建一个cry文件,也可以拷贝过去;至于具体的路由,这个也可以知己拷贝,当然list的登录模块可以展示注释,还没有实现登录,而且返回的话现在是使用res.json。这样基本就可以调用数据库了。 

router.get('/list',function(req,res,next) {let author = req.query.author || ''
const keyword = req.query.keyword || ''const result = getlist(author,keyword)
return result.then(listdata) => 
{res.json(
new SuccessModel(listdata))
}}

2.express处理session

登录:

  • 使用express-session和connect-Redis,简单方便;
  • req.session保存登录信息,登录校验做成express中间件
先安装 express-session,让我们轻松实现 session 的功能,原理与之前相同,在 app.js 引入该插件。 使用的话也是和一般的中间件一样,直接 app.use,只不过里 面需要写成函数,然后会返回一个中间件。该函数需要几个 参数:secret(即密匙)、cookie(配置 path,这里设置为/ 根目录,这样子到处都可以用,还有 httpOnly 设置为 true, 当然这两个都是默认配置,写不写一样的而 maxAge 直接传入一个时间段即可,相比之前的 expire 要简洁,这里写 24 小时)。
如此我们随意访问一个路由就可以自动设置 session,我们还可以设置一个路由来测试,在这里可以通过 req.session 拿到session(主要是因为写注册 session 在注册路由之前!)
router.get(''/session-test),function(req,res,next) {const session = req.sessionif(session.viewNum == null) {session.viewNum = 0;
} 
session.viewNum++
res.json({viewNum:session.viewNum
})});

处理session

app.use(session({secret:'ODST123!#',
cookie:{
path:'/',
httpOnly:true,
maxAge:24*60*60*1000}
)

3.session链接redis

通过不同浏览器访问 session-test 确实可以看到不同的访问 数量说明有在区分用户了。 接下来实现登录,这个直接去拷贝就行。注意这里不需要再手动加到 redis,在设置 session 的时候就已经自己加了。而且返回也记得改成 res.json。 再定义一个测试是否已经登录的路由 login-test。 在实现了登录功能后,我们需要连接 redis 了,很简单,先安装 redis connect-redis 包。在 db 下面建一个 redis.js,直接拷贝之前的 redis(到客户端那一部分就行)。 然后回到 app.js 引入这个库(是函数所以让它立即执行且传入 session)为 RedisStore。 然后在 session 之前,引入redisClientnew 一个 RedisStore 把其传进去就行作为配置。现在 session 就可以多一个配置
store,传入 sessionStore 就行(之前没有写就是存在内存里,现在 redis 了)。

 

router.get('/login-test',function(req,res,next){if(req.session.username) {res.json({errno:0
msg:'已经登录'})
return}res.json({
errno:1,
msg:'没有登录'
})
})

 到此呢,可以实现登录验证同时还可以通过 test 查看登录状态(即登录 or 未登录)。


4.登录中间件

我们查看 redis 可以看到已经储存了 session,同时登录的话也会把一些公开的个人信息传进去。那么我们就能回到 blog 去处理登录权限(当然 check 还不能实现)接下来做一个登录校验,新建一个 middleware 文件夹,下面 建一个 loginCheck.js 文件,引入 ErrorModel,输出一个中间 件,判断是否登录(其实就是刚才写的 test!)如果登录则调用 next()然后 return,如果没有登录返回错误 model。 自此我们的登录就全部完成了。
   问题:使用插件时提示某某插件的函数不存在,很简单,肯定是传入这个插件的参数出错了,这里是发现 redis 向外暴露函数的时候不是默认暴露,引用的话也是奇葩直接引入文 件,反正规范一下引入导出就可以了。
const redis = reqiure('redis')
const { REDIS_CONF } = require('../conf/db')//创建一个客户端
const redisClient = redis.createClient(REDIS_CONF.portm,REDIS_CONF.host)
redisClient.on('error',err=>{
console.log(err)
})module.exports = redisClient
到这里我们进入任意页面都会在 redis 触发缓存 session(只 不过没有登录的话里面没有个人信息),登录后会在 session添加个人信息,下一步有了 redis,就可以解法 blog(一部分)

 定义登录校验的中间件;


5.开发路由 

修改 blogs,虽然没有写 check 校验,但是我们可以直接通过 是否有 username 来校验,如果等于 null 直接就返回错误 model。(如此未登录访问管理员界面就会报错) 接下来写 detail 路由,直接拷贝,id 的话通过 req.query.id 拿 到,且记得 res.json 返回。 接下来写 new,中间件写箭头函数还是普通的 function 都行 (但是要统一),这个需要引入之前写的登录中间件,直接就能在参数中用。 更新也要登录中间件也是直接用就行。删除操作也是如此。 像现在这种一个一个函数就很好拆分,不会说都是一个个 if 什么的,另外登录也写成了中间件放在外面,比较规范标准(其它地方也可以使用)。 总结一下就是换成 res.json、需要登录校验的引入登录中间件 为参数、拿不到的参数(未全局定义)换成 req.query.参数。

 

 

 


6.Morgan 

关于自定义日志直接打印自然是不会记到文件,但是后面PM2 有办法记到文件;
  1. access log记录,直接使用脚手架推荐的Morgan;
  2. 指定以日志使用console.log和console.log就可以了;
  3. 日志文件拆分、日志内容分析,之前说过,就不说了

使用Morgan写日记

 目前已经有日志了,只不过是直接打印在控制台且内容有点 少。这个还可以再加一个参数(对象),其中配置 stream: process.stdout(则会打印在控制台,默认参数,不加也一样, 也是用流来输出!)。 那么第一个参数是什么意思,我们可以访问 github 找到 predefined Formats 找到有关第一个参数的信息,有多种情况,简单来说就是规定了输出的内容/格式(不同情况输出不 同内容,有 devshottiny 等等),输出内容比较丰富完整的是 combined(线上用)。

 既然有多种情况,那么是时候来设置另一个环境 prd 了(暂 时用 nodemon 代替,正式是用pm2)。 回到 app.js 添加一个 ENV 变量来判断当前环境,如果不是线上环境直接用之前的日志,打印到控制台就行。如果是线上环境就改成 combinedstream 也要改。我们建多一个 logs里面建多一个 access.log,引入 fs path,生成文件名、写入流,stream 就可以指向这个写入流就行。那么日志就会写 入到文件中。 所以这样子直接用就比较规范标准,也不需要考虑怎么写入 文件的。(懂原理且会用工具) 接下来就是自定义日志,直接在需要的任意地方打印任意信 息即可

 


7.中间件原理 

express中间件原理:

  1. 回顾中间件使用;
  2. 分析如何实现;
  3. 代码演示

 这个我们只是实现大体的中间件,就不一定源码就是这么实现。回顾中间件的话我们看之前写的 express-test 就行,那么怎么 实现,至少 uselistengetpostnext 接口怎么去实现。 而且 usegetpost 要兼容只传入一个中间件的情况和传入一个中间件加路由和传入多个中间件加路由的情况。

分析

  1. app.use使用注册中间件,先收集起来;
  2. 遇到http请求,根据path和mothod判断触发哪一个;
  3. 实现next机制,机制,即上一个通过next触发下一个;

8.中间件原理-代码实现 

  新建一个 lib(库),建一个 express 文件夹,下面建一个 like-express.js,就在这里写中间件。
引入 http,然后把数组的 slice 方法单独定义成一个常量。建一个 LikeExpress 类,然后返回这个类的实例(以函数的形式在里面返回类的实例,即工厂函数)。 类里面定义一个构造函数,定义一个存放中间件的列表(all、 get、post,这些都以数组形式),然后就可以定义 useget
postlisten 四个函数。
   由于其中三个函数都有类似的部分如注册中间件故抽离出来,只需要传入一个参数 path。定义一个 info 空对象保存注册信息,判断参数是字符串否是就是路由放到 info,不是就默认为/根路由,因为如果第一个参数不是路由也就是说没有写路由,其实也应该认为有路由且是根路由,只不过是被忽略了。
   如果带路由的话我们切掉第一个参数并且利用 slice 把剩下参数变为数组,如果不带的话就直接从第一个参数开始转化为数组。最后返回 info 对象即可,也就是说 register 函数只是对传入的参进行处理,带路由的保存路由且剩下参数变为数组存入 stack,如果不带路由保存根路由且全部参数变为数组存入 stack
   接下来看 use,利用 apply 把参数丢到 register 函数,再将得到的传入列表,get post 也是如此,只不过放到不同的数 组。
  接下来写 listen,它可以传多个参数,我们解构一下,调用createServer 方法,需传入回调函数(在外面定义),然后简化解构的参数放到 listen 里面就行了,也就是说我们用了 node.js 本身的 listen 方法而不是自己去写,这就很好。 写回调函数返回一个 res.json 函数,设置表头和返回数据, 接下来获取 url method,因为要区分哪些需要访问哪些不 需要访问,通过 match 函数(外面定义)分析(需要传入 url 和 method),传给一个变量。 match 函数呢,定义一个 stack 数组来存储需要返回需要访问的路由什么的,如果是发送图标的,我们大可不管直接返回。 再定义一个获取具体请求类型的数组,其实我们只需要拿到全部的路由,再传入 method 让它们自己看明白谁是要获取就行了(就限制了 method 已经),之后就可以遍历该数组,
   通过 path 来限制,将符合路径要求的丢到 stack。回到回调函数,还需要再调用一个 handle 函数,传入 req、 res 和 stack,主要是控制 next 如何往下。首先里面调用一个 next函数然后立即执行,通过数组的shift拿到第一个中间件,如果存在则立刻执行中间件的函数,而且还要把 next 传进去实现套娃。

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_395727.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2022年Webpack 5初学者完整指南

2022年Webpack 5初学者完整指南 从基础到高级学习 Webpack 5!将 Webpack 与 JS、CSS、NPM、模块联合和微前端一起使用 课程英文名:Webpack 5 in 2022 The Complete Guide For Beginners 此视频教程共2.5小时,中英双语字幕,画质…

都这麽大了还不快了解防病毒网关?

目录 一、思考 二、实验 1、实验拓扑 2、配置过程(网页端配置) 三、总结 1. 什么是恶意软件? 2. 恶意软件有哪些特征? 3. 恶意软件的可分为那几类? 4. 恶意软件的免杀技术有哪些? 5. 反病毒技术…

OceanBase 从0到1数据库内核实战教程学习笔记 - 3.OceanBase基础架构和开发技巧

这篇文章主要介绍王泽林老师分享的 《OceanBase 的基础架构和开发技巧》。如果您看过第一篇文章的对应视频,会发现整个系列主要分为 MiniOB 和 OceanBase 两个系列,本篇文章就是 OceanBase 系列的开篇,所以文章中会有很多 OceanBase 的概念和…

Java类的成员方法的创建以及调用|在使用时有何意义|附运行方式及题目

🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝 🥇博主昵称:Jovy. 🍟博客主页…

遥感航拍影像25篇CVPR39个数据集

摘要 本文讲解了39个数据集,关于高空卫星图和低空无人机航拍图像。 本文汇总了25篇CVPR2020年和2021年的论文。 本文详细介绍了这25篇论文的任务是什么,难点是什么,场景是什么。 同时,本文在需要的地方解释了一些卫星图和航拍…

Vue学习第35天——模拟项目上线基本流程

一、打包 将.vue文件生成为.html、.css、.js文件 npm run build执行完之后,会在项目中生成一个dist文件(执行的速度取决于项目的大小以及电脑的配置) 二、创建服务器 没有后端服务器,这里我们使用node.js express 搭建一个服…

(附源码)计算机毕业设计ssm餐厅管理系统

毕设帮助,指导,本源码分享,调试部署(见文末) 4.1.2系统的主要的功能结构 餐厅管理系统的主要功能的结构如图4-1所示。 图4-1系统功能结构图 4.2系统设计 4.2.1数据表E-R图 菜谱信息属性图如图4-2所示。 图4-2菜谱信息实体属性图 账单信息…

3、数据类型中的数据位置,stograge、memory、calldata

数据位置 所有的复杂类型,即 数组 和 结构 类型,都有一个额外属性,“数据位置”,说明数据是保存在 内存memory 中还是 存储storage 中。 根据上下文不同,大多数时候数据有默认的位置,但也可以通过在类型名后增加关键字 storage 或 memory 进行修改。 函数参数(包括返回的…

Day11 栈和队列

150. 逆波兰表达式求值 解法一:将计算部分抽象成一个函数,使代码更加简洁,避免了很多冗余操作。对比下面解法二(我自己写的),此解法(参考别人的)的代码更加精简。核心思想都是利用栈…

Linux学习 -- Shell面试题练习

1、使用Linux命令查询file1中空行所在的行号 awk /^$/ {print NR} file1 // 使用正则表达式^$ 来表示空行 2、使用Linux命令计算文件a.txt的第二列的和并输出 张三 40 李四 50 王五20 cat a.txt | awk -F " " {sum$2} END {print sum} 3、Shell脚本中如何检查一个文…

欧拉函数的power

在算数基本定理中有 $ N = p_{1}^{a1} p_{2}^{a2} p_{3}^{a3} ..... p_{k}^{ak} $ wuw在y总的课中是用了容斥原理进行推导得到了 $ \phi(x) = N * (1 - \frac{1}{p1}) * (1 - \frac{1}{p2}) * .... * ( 1 - \frac{1}{pk}) $ 所以就可以得到依靠该公式得出的欧拉公式的算法 #in…

基本语法

输入输出输入: 输出:字符串: System.out.println("hello world!"); 字符串+数值 System.out.println("a =" + 8);import java.util.Scanner; //Scanner 是一个简单的文本扫描器public class MyInput {public static void main(String[] Args) {Scanne…

cat笔记

0.学习目标 能够知道什么是CAT能够搭建CAT服务端环境能够进行CAT客户端的集成能够使用CAT监控界面进行服务监控能够完成CAT和常用框架集成了解CAT告警配置了解CAT客户端和服务端原理 1.CAT入门 在这一部分我们主要介绍以下3部分内容: 什么是调用链监控 什么是CA…

【虚幻引擎UE】UE5 阴影异常与优化解决方案合集

一、消除阴影锯齿 异常效果: 模型锯齿状阴影。 解决方案: ① 确定打开虚拟阴影贴图。 虚拟阴影贴图(VSM)是一种全新的阴影贴图方法,可以提供稳定的高分辨率阴影。通过与虚幻引擎5的Nanite虚拟几何体、Lumen全局光照和…

Seata安装

文章目录一、下载二、MySQL配置三、Nacos配置四、启动参考一、下载 从Seata下载地址下载 https://github.com/seata/seata/releases 这里下载的是seata-server-1.5.2.tar.gz 解压: tar -xvf seata-server-1.5.2.tar.gz修改配置:conf/application.ym…

Python实战——全球疫情数据采集, 并做可视化

前言 大家早好、午好、晚好吖~ 知识点: 爬虫基本流程 requests 发送请求 re 正则表达式 json 结构化数据解析 开发环境: python 3.8: 解释器 pycharm: 代码编辑器 requests 发送请求 pyecharts 绘制图表 pandas 读取数据 基本原理: 模拟成 浏览器/客户端 向 服务器…

React-Hooks源码深度解读

useState 解析 useState 使用 通常我们这样来使用 useState 方法 function App() {const [num, setNum] useState(0);const add () > {setNum(num 1);};return (<div><p>数字: {num}</p><button onClick{add}> 1 </button></div>…

I2C 时序、速率计算及intel I2C驱动

目录 速率 信号 时序定义 START ACK NACK STOP 时序实战 速率计算 数据解读 异常时序 上拉电阻 I2C的设备驱动 速率 主要支持的速率如下&#xff1a; 100Kbps 400Kbps 1Mbps 3.4Mbps 信号 SDA 数据 SCL 时钟 时序定义 START SCL为高电平时&#xff0c;SD…

【FineReport企业日常问题 1.0】帆软决策服务端管理员密码忘记怎么办?

文章目录企业问题描述分析问题加密方式分类原理问题解决企业问题描述 有的时候我们在进行帆软部署的时候&#xff0c;设置管理密码的不小心忘记(当然这个是属于小概率事件) 其实是有相应的办法解决的~ 分析问题 首先&#xff0c;我们来了解一下帆软的加密算法 加密方式分类…

Angr学习 00_angr_find

Angr学习 00_angr_find1. github下载angr项目2. angr安装3. IDA静态分析4. angr使用说明5. exp6.运行结果1. github下载angr项目 点击前往github 2. angr安装 网上的教程都是要安装什么虚拟环境我也安装了但是可能因为我是初学者不知道这个虚拟环境有什么用我直接在shell中用…