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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: 这个时候我们就可以去把一些自己带有的不用的注释,安装一下我们的mysql和xss.新建一个db文件夹,新建一个mysql.js,将其中的内容拷贝过去,在新建一个conf文件夹,下面建一个db.js,也可以拷贝。

前言

承接上一篇文章,《前端升全栈之项目使用express重构项目(上篇)》,我们继续讲解下一篇的项目使用express重构项目完整的下一篇,好了,我们马上进入我们今天的正题!!!

1.express开发项目

express开发接口:

  1. 初始化接口,之前的部分代码可以复用;
  2. 开发路由,并可以实现登录功能;
  3. 记录日志;
  4. 初始化环境:
  5. 安装插件mysql xss;
  6. mysql control resModel 相关代码可以复用;
  7. 初始化路由;

这个时候我们就可以去把一些自己带有的不用的注释,安装一下我们的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.session
  if(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 之前,引入 redisClient , new 一个 RedisStore 把其传进去就行作为配置。现在 session 就可以多一个配置

store ,传入 sessionStore 就行(之前没有写就是存在内存里,现在 redis 了)。

2345_image_file_copy_511.jpg

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 (一部分)

2345_image_file_copy_512.jpg

 定义登录校验的中间件;

2345_image_file_copy_513.jpg

5.开发路由

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

2345_image_file_copy_514.jpg

2345_image_file_copy_515.jpg

2345_image_file_copy_516.jpg


2345_image_file_copy_517.jpg

6.Morgan

关于自定义日志直接打印自然是不会记到文件,但是后面PM2 有办法记到文件;

  1. access log记录,直接使用脚手架推荐的Morgan;
  2. 指定以日志使用console.log和console.log就可以了;
  3. 日志文件拆分、日志内容分析,之前说过,就不说了

使用Morgan写日记

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

2345_image_file_copy_518.jpg

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

2345_image_file_copy_519.jpg

7.中间件原理

express中间件原理:

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

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

分析

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

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

 新建一个 lib (库),建一个 express 文件夹,下面建一个 like-express.js,就在这里写中间件。

引入 http ,然后把数组的 slice 方法单独定义成一个常量。建一个 LikeExpress 类,然后返回这个类的实例(以函数的形式在里面返回类的实例,即工厂函数)。 类里面定义一个构造函数,定义一个存放中间件的列表(all、 get、 post ,这些都以数组形式),然后就可以定义 use 、 get 、

post 、 listen 四个函数。

  由于其中三个函数都有类似的部分如注册中间件故抽离出来,只需要传入一个参数 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 传进去实现套娃。

2345_image_file_copy_521.jpg

2345_image_file_copy_522.jpg

2345_image_file_copy_523.jpg

2345_image_file_copy_524.jpg

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
前端开发 JavaScript 定位技术
一、前端高德地图注册、项目中引入、渲染标记(Marker)and覆盖物(Circle)
文章介绍了如何在前端项目中注册并使用高德地图API,包括注册高德开放平台账号、引入高德地图到项目、以及如何在地图上渲染标记(Marker)和覆盖物(Circle)。
97 1
|
2月前
|
JavaScript 前端开发 Docker
前端全栈之路Deno篇(二):几行代码打包后接近100M?别慌,带你掌握Deno2.0的安装到项目构建全流程、剖析构建物并了解其好处
在使用 Deno 构建项目时,生成的可执行文件体积较大,通常接近 100 MB,而 Node.js 构建的项目体积则要小得多。这是由于 Deno 包含了完整的 V8 引擎和运行时,使其能够在目标设备上独立运行,无需额外安装依赖。尽管体积较大,但 Deno 提供了更好的安全性和部署便利性。通过裁剪功能、使用压缩工具等方法,可以优化可执行文件的体积。
135 3
前端全栈之路Deno篇(二):几行代码打包后接近100M?别慌,带你掌握Deno2.0的安装到项目构建全流程、剖析构建物并了解其好处
|
1月前
|
前端开发 Unix 测试技术
揭秘!前端大牛们如何高效管理项目,确保按时交付高质量作品!
【10月更文挑战第30天】前端开发项目涉及从需求分析到最终交付的多个环节。本文解答了如何制定合理项目计划、提高团队协作效率、确保代码质量和应对项目风险等问题,帮助你学习前端大牛们的项目管理技巧,确保按时交付高质量的作品。
34 2
|
2月前
|
前端开发 JavaScript 应用服务中间件
linux安装nginx和前端部署vue项目(实际测试react项目也可以)
本文是一篇详细的教程,介绍了如何在Linux系统上安装和配置nginx,以及如何将打包好的前端项目(如Vue或React)上传和部署到服务器上,包括了常见的错误处理方法。
561 0
linux安装nginx和前端部署vue项目(实际测试react项目也可以)
|
2月前
|
缓存 前端开发 JavaScript
前端架构思考:代码复用带来的隐形耦合,可能让大模型造轮子是更好的选择-从 CDN 依赖包被删导致个站打不开到数年前因11 行代码导致上千项目崩溃谈谈npm黑洞 - 统计下你的项目有多少个依赖吧!
最近,我的个人网站因免费CDN上的Vue.js包路径变更导致无法访问,引发了我对前端依赖管理的深刻反思。文章探讨了NPM依赖陷阱、开源库所有权与维护压力、NPM生态问题,并提出减少不必要的依赖、重视模块设计等建议,以提升前端项目的稳定性和可控性。通过“left_pad”事件及个人经历,强调了依赖管理的重要性和让大模型代替人造轮子的潜在收益
|
2月前
|
前端开发 JavaScript 开发工具
前端代码规范和质量是确保项目可维护性、可读性和可扩展性的关键(三)
前端代码规范和质量是确保项目可维护性、可读性和可扩展性的关键(三)
38 0
|
2月前
|
Web App开发 前端开发 JavaScript
前端代码规范和质量是确保项目可维护性、可读性和可扩展性的关键(二)
前端代码规范和质量是确保项目可维护性、可读性和可扩展性的关键(二)
53 0
|
2月前
|
Web App开发 移动开发 前端开发
前端代码规范和质量是确保项目可维护性、可读性和可扩展性的关键(一)
前端代码规范和质量是确保项目可维护性、可读性和可扩展性的关键(一)
51 0
|
2月前
|
前端开发 API 开发者
🥇前端宝藏:多项目掌握技能的冒险之旅🏆
在前端开发的学习旅程中,实践是提升技能的关键。本文介绍了多个前端项目,包括计算器、天气应用、经典游戏等,涵盖了从React到Svelte的各种技术栈。每个项目都附有在线演示和源代码,旨在帮助读者深入理解实现细节,激励更多人参与实际项目开发。通过这些项目,读者可以将理论知识转化为实践,拓展职业机会。
19 0
|
2月前
|
前端开发 JavaScript
轻松上手:基于single-spa构建qiankun微前端项目完整教程
轻松上手:基于single-spa构建qiankun微前端项目完整教程
52 0