当前位置: 首页 > news >正文

附录3-大事件项目后端-项目准备工作,config.js,一些库的简易用法,main.js

目录

1  一些注意

2  创建数据库

3  项目结构

4  配置文件 config.js

5  参数规则包 @hapi/joi与@escook/express-joi

5.1  安装

5.2  文档中的demo

5.2.1  定义规则

5.2.2  使用规则

5.3  项目中的使用

5.3.1  定义信息规则

5.3.2  使用规则

6  密码加密包 bcrypt.js

6.1  加密

6.2  对比

7  处理form-data数据包 multer

7.1  安装

7.2  项目中的使用

8  入口文件 main.js

8.1  约束一些请求

8.2  注册所有路由模块

8.3  处理请求体


1  一些注意

  • 不要认为接口中的message没什么用就不写了,写上在排错与前端调用的时候都比较方便
  • 这里面记录了该项目后端的详细实现方式 api_server_ev 在这个链接中关于文章列表后面几个视图没有写
  • 如果只看接口文档可以看这个 ShowDoc
  • 在实际开发的时候express有时会出现错误后服务就断掉,且与其他模块可能会出现协同性的问题(不是一家开发的,比如mysql出现了问题,给express错误处理中间件服务也会断掉)
  • 实际开发中应该将路由与视图不在同一个文件写符合模块化开发的要求,我这里就写在一起了,因为对于一个小项目来讲,一共就十几个url,摊到每个模块也就四五个url,你过度封装反而会导致你维护的时候不好找,一会儿点开这个一会儿点开那个。分开写的原因是当路由多的时候可以一个人搞路由一个人搞视图,分开写的缺点是从主函数到视图函数会出现多级的调用,对于单人开发就显得不是很友好
  • 大事件项目后端视频 07.项目-初始化项目_哔哩哔哩_bilibili P77-P96

2  创建数据库

数据库使用的是mysql,数据表有三个,分别是 用户信息数据表,文章分类数据表,文章内容数据表

三个数据表的这些信息都是一样的

用户信息数据表,其中user_pic是用户头像,要求为base64字符串,我们的Datatype可以写为TEXT

文章信息数据表

文章分类数据表

三张表都是没有外键的,我们让用户在上传文章的时候要上传用户id(后端根据token自动添加参数),然后显示的时候根据用户id进行筛选(后端根据token自动筛选),从而用户只会看到自己的文章

文章分类没有给author_id,实际上也可以再加一个author_id,让每一个用户都有自己专属的分类

3  项目结构

项目结构如下,最上面的uploads放前端传过来的文章封面,config.js中有一些配置,main.js是入口文件,运行的时候node main.js

router是四个模块的路由

4  配置文件 config.js

我使用了一个config.js文件作为配置文件,里面有很多的全局变量,config文件内容没有做导出,在使用的时候直接引入config就行了

config.js中有需要导入的库,token密钥,数据库配置,文章封面存放的文件夹,以及一些验证规则

// 需要导入的库
joi = require('joi')
mysql = require('mysql')
express = require('express')
jsonwebtoken = require('jsonwebtoken')
bcryptjs = require('bcryptjs')
expressJoi = require('@escook/express-joi')
cors = require('cors')
multer = require('multer')
path = require('path')// token密钥
secretKey = 'xifgnmuioherawbt'// 数据库
db = mysql.createPool({host:'127.0.0.1',user:'root',password:'12345678',database:'big_things'
})// 文章封面存放的文件夹
uploads = multer({dest:path.join(__dirname,'../uploads')})// id的验证规则都是相同的,所以可以统一来写
id_rule = joi.number().integer().min(1).required()
// 用户信息表 验证规则
userinfo_username_rule = joi.string().alphanum().min(1).max(10).required()
userinfo_password_rule = joi.string().pattern(/^[\S]{6,12}$/)userinfo_nickname_rule = joi.string().required()
userinfo_email_rule = joi.string().email().required()
userinfo_avatar_rule = joi.string().dataUri().required()// 文章分类表 验证规则
category_name_rule = joi.string().required()
category_alias_rule = joi.string().alphanum().required()// 文章列表 验证规则
article_title_rule = joi.string().required()
article_content_rule = joi.string().required().allow('')
// 分类id与状态 有的时候需要必选,有的时候不需要必选,所以在总的规则中取消了required(),需要的时候你再加上就行了
article_cate_id_rule = joi.number().integer().min(1)
article_state_rule = joi.string().valid('已发布', '草稿')
// 文章列表要做分页,pagenum是要看第几页
article_pagenum_rule = joi.number().integer().min(1).required()
// pagesize是每页显示多少条数据
article_pagesize_rule = joi.number().integer().min(1).required()

简单看一下导入的库

  • joi与express-joi 前端传入信息规则验证
  • mysql 数据库
  • express 后端框架
  • jsonwebtoken 做token的,用于前后端跨域信息验证
  • bcryptjs 密码加密
  • cors 做跨域的
  • multer 处理前端传入的form-data数据的
  • path 路径拼接

其中 mysql在这里有具体用法 8.mysql模块_Suyuoa的博客-CSDN博客

express,jsonwebtoken,cors在这里有具体用法 7.Express模块基础用法_express 引入模块_Suyuoa的博客-CSDN博客

5  参数规则包 @hapi/joi与@escook/express-joi

后端是一定要加数据验证的,不要因为前端做了验证后端就不做了,宁可多做不要少做

我们如果每个验证都写if else那样的话代码量较多,维护起来比较麻烦,我们可以借助一些第三方的包来搞

如果规则较简单的时候也可以不用,轮子太多也不利于项目的维护,有时候搞来搞去发现轮子不好用,最好还有查轮子的文档,比如我就遇到了这个问题,还得在网上查一下怎么搞定这个错误 【node.js】报错Cannot mix different versions of joi schemas解决方法_前端小二哥的博客-CSDN博客

@hapi/joi 是定义规则用的,@escook/express-joi 是验证规则用的

@hapi/joi是@escook/express-joi的依赖,在导入的时候要先导入@hapi/joi再导入@escook/express-joi

5.1  安装

5.2  文档中的demo

在npm官网上搜索@escook/express-joi会出现它的简易demo

5.2.1  定义规则

我们看userSchema这个对象,其中有body,query,params,分别的意思就是req.body,req.query,req.params

有什么写什么就行,比如只验证req.body,就只写body就行

body,query,params这三个名称固定

下面看body中的内容,里面username这些是参数名,后面跟的是验证规则。可以给验证规则自己定义一个变量方便复用

验证规则的名字一般我们保持与接收的参数名一致就行,如果不一致你就需要这样写

  • 实则还是遵循键值的格式

Joi.string()是先让其变成字符串形式,Joi.number().integer()是让其先变成数字型然后变为整形

alphanum()表示这个字符串中只能包含 a-z A-Z 0-9

min()与max()是字符串的最小,最大长度,如果类型是数字那么就代表最大值最小值

required()表示是必选参数

patter()内加正则表达式用于验证规则

repassword这个就是重新输入密码的参数名,joi.ref('password')的意思是必须与password保持一致

只有写在body中的内容才会被接收,如果你多给了是存不到req.body中的,比如上面我给了id,nickname.email,如果你再多给一个password,最后你查req.body中是没有password的

5.2.2  使用规则

userSchema是我们刚刚定义的规则,如果在路由中出现了验证不通过的情况就会抛出一个错误,抛出错误后下面定义一个错误级别中间件,这个错误级别中间件会把错误的信息返回给客户端

5.3  项目中的使用

5.3.1  定义信息规则

我们下面看一下传入信息的规则,规则都放在config.js中,搞的全局变量,后面在验证的时候直接使用这个全局变量就好

  • number() 必须为数字
  • integer() 必须为整形
  • min(1) 当值为数字时,最小值为1,当值为字符时,最小长度为1
  • required() 必须传入
  • string() 必须为字符串
  • alphanum() 只能包含 a-z,A-Z,0-9
  • max(10) 当值为数字时,最大值为10,当值为字符时,最大长度为10
  • pattern(/^[\S]{6,12}$/) pattern中是正则的用法,这里是6-12位非空字符串
  • email() 必须为邮箱格式
  • dataUri() 比如是dataUri格式,比如 'data:image/png;base64,VE9PTUFOWVNFQ1JFVFM=' 项目中用其处理base64图像字符串
  • allow('') 允许为空
  • valid('已发布', '草稿') 值只能为 已发布 或 草稿

5.3.2  使用规则

首先定义一个对象,如果是get的查询字符串传递就写query

如果是post就写body,form-data与xxx-www-form-urlencoded都用body

如果是拼接路由就用params

当有不符合规则的信息时,在main.js中加入一个中间件,提示客户端错误信息

6  密码加密包 bcrypt.js

可以通过 beryptjs 来对密码部分进行加密,首先定义一个密钥,这个密钥就随便写就行,密码会根据这个密钥进行加密与解密,我在config.js中定义了一个全局变量secretKey

6.1  加密

在注册的时候,加密后存储数据库,加密方法为 bcryptjs.hashSync(),第一个参数为加密的内容,第二个参数是哈希烟的长度

  • 即使是相同的密码也会得到不同的加密结果

6.2  对比

使用bcyptjs.compareSync()将传入的密码与数据库中存储的真实密码进行比对

7  处理form-data数据包 multer

multer是处理 multipart/form-data 表单上传的数据用的(Multer 不会处理任何非 multipart/form-data 类型的表单数据)

7.1  安装

7.2  项目中的使用

我们先看几个关于multer的信息

传上来的文件被存储在uploads文件夹中,每一次成功传输会生成一个这样的文件

在mysql中会存储文件的路径

下面我们来看使用

在config.js中,我们指定了一个文件夹用来放文章封面,dest这个键就是放在那个位置的意思

  • 这里只是管把文件存在哪个实际的地方,和数据库中的数据无关

使用single()方法,参数为传递的文件参数名,single()方法会让cover_img存在req.file中,我们打印出 req.file.filename 看一下

打印出来的结果只有文件名

下面用path.join()只和数据库中的信息有关,和实际文件存在哪里无关

8  入口文件 main.js

const config = require('./config.js')const login_register_router = require('./router/login_register.js')
const personal_center_router = require('./router/personal_center.js')
const article_category_management_router = require('./router/article_category_management.js')
const article_list_management_router = require('./router/article_list_management.js')const { expressjwt: jwt } = require("express-jwt")const app = express()app.use(function (req, res, next) {res.setTimeout(5*1000, function () {res.send("请求超时")});next();
});
app.use(jwt({secret: secretKey,algorithms: ["HS256"],}).unless({ path: [/^\/api\//] })
)
app.use(cors())
app.use(express.urlencoded({extended:false}))app.use(login_register_router)
app.use(personal_center_router)
app.use(article_category_management_router)
app.use(article_list_management_router)app.use((err,req,res,next) => {// 判断用户提交的信息if (err instanceof joi.ValidationError) return res.send({status:1,message:err.message})// 判断tokenif (err.name === 'UnauthorizedError') {return res.send({status:1,message:'无效的token'})}// 其他错误return res.send({status:1,message:err.message})
})app.listen(80,() => {console.log('服务在80端口启动')
})

首先引入配置文件和所有的路由模块

引入jwt,只有在main.js中需要,所以就在这里引入了,而且这个库的引入方式有一点奇特,不方便在config.js中引入

初始化一个app

8.1  约束一些请求

放一个中间件,当请求时间超过5秒时,返回请求超时

放一个中间件,只有使用/api开头的路由不需要token,其余均需要token

支持跨域

支持前端post发送一些信息

8.2  注册所有路由模块

8.3  处理请求体

第一个if用来处理用户提交的信息(我们上面用joi定义的那些规则),第二个if用来判断token

在80端口启动

相关文章:

附录3-大事件项目后端-项目准备工作,config.js,一些库的简易用法,main.js

目录 1 一些注意 2 创建数据库 3 项目结构 4 配置文件 config.js 5 参数规则包 hapi/joi与escook/express-joi 5.1 安装 5.2 文档中的demo 5.2.1 定义规则 5.2.2 使用规则 5.3 项目中的使用 5.3.1 定义信息规则 5.3.2 使用规则 6 密码加密包 bcrypt.…...

并发编程-线程

并发编程-线程 一个进程是操作系统中运行的一个任务,进程独立拥有CPU、内存等资源一个线程是一个进程中运行的一个任务,线程之间共享CPU、内存等资源,进程里的每一个任务都是线程。 线程创建 创建线程:使用threading模块中的Th…...

图解LeetCode——剑指 Offer 34. 二叉树中和为某一值的路径

一、题目 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。 二、示例 2.1> 示例 1: 【输入】root [5,4,8,11,null,13,4,7,2,null,null,5,1], t…...

使用Python免费试用最新Openai API

一、背景介绍 3月2日凌晨,OpenAI放出了真正的ChatGPT API,不是背后的GPT-3.5大模型,是ChatGPT的本体模型!ChatGPT API价格为1k tokens/$0.002,等于每输出100万个单词,价格才2.7美金(约18元人民…...

04、启动 SVN 服务器端程序

启动 SVN 服务器端程序1 概述2 用命令行单项目启动2.1 采用 svnserve 命令2.2 验证服务是否启动2.3 命令行方式的缺陷3 注册Windows服务3.1 注册服务的命令3.2 命令说明3.3 启动服务1 概述 SVN 服务器和 Tomcat 服务器,Nexus 服务器一样, 必须处于运行状态才能响应…...

jsp船舶引航计费网站Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP船舶引航计费网站是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…...

Allegro如何画半圆形的线操作指导

Allegro如何画半圆形的线操作指导 在用Allegro设计PCB的时候,在某些应用场合会需要画半圆形,如下图 如何画半圆形,具体操作如下 点击Add点击Arc w/Radius...

【强烈建议收藏:MySQL面试必问系列之SQL语句执行专题】

一.知识回顾 之前的文章我们一起学习了MySQL面试必问系列之事务专题、锁专题,没有学习的小伙伴可以直接通过该链接地址直接访问,MYSQL你真的了解吗专栏的文章,接下来我们就一起来学习一下MySQL中SQL语句的执行流程,看看你掌握的怎…...

详解Linux下的环境变量以及C++库文件和头文件、python库的配置

目录 Linux环境变量配置基本步骤 1.查看环境变量 2.设置环境变量 3.永久性设置环境变量 4.使用环境变量 C 库文件和头文件环境变量配置 1.配置so库文件的环境变量 2.配置头文件的环境变量 Python库环境变量配置 Linux配置执行文件环境变量 我们都习惯在Windows 上配置…...

企业级分布式数据库 - GaussDB介绍

目录 什么是GaussDB 简介 应用场景 产品架构 产品优势 安全 责任共担 身份认证与访问控制 数据保护技术 审计与日志 ​​​​​​​监控安全风险 ​​​​​​​故障恢复 ​​​​​​​认证证书 GaussDB与其他服务的关系 约束与限制 计费模式 什么是GaussDB …...

Linux I2C 驱动实验

目录 一、Linux I2C 驱动简介 1、I2C 总线驱动 2、I2C 设备驱动 1、 i2c_client 结构体 2、 i2c_driver 结构体 二、硬件分析 三、设备树编写 1、pinctrl_i2c1 2、在 i2c1 节点追加 ap3216c 子节点 3、验证 四、 代码编写 1、makefile 2、ap3216c.h 3、ap3216c.c …...

DC-DC模块电源隔离直流升压高压稳压输出5v12v24v转60v100v110v150v220v250v300v400v500v

特点效率高达80%以上1*1英寸标准封装单电压输出稳压输出工作温度: -40℃~85℃阻燃封装,满足UL94-V0 要求温度特性好可直接焊在PCB 上应用HRB 0.2~10W 系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为:4.5~9V、9~18V、及18~36VDC标准&#…...

EF有几种模式,EF的三种模式分别是什么?

EF有几种模式,EF的三种模式分别是什么? 第一种:DataBase First DataBase First传统的表驱动方式创建EDM,然后通过EDM生成模型和数据层代码。除生成实体模型和自跟踪实现模型,还支持生成轻型DbContext。 解释&#xf…...

数据可视化展示:打工人常见职业病,颈腰椎病占比最高达66.51%

身体健康才是一切的根本。只有身体健健康康才能更好的去享受世间的美好,无论是谁都应当注重身体健康,而不是无度的挥霍它! 良好的身体,释放给工作,健壮的体魄,享受美好生活,良好的心态&#xff…...

【食品图像识别】Large Scale Visual Food Recognition

1 引言 视觉智能部与中科院计算所于2020-2021年度展开了《细粒度菜品图像识别和检索》科研课题合作,本文系双方联合在IEEE T-PAMI2023发布论文《Large Scale Visual Food Recognition》 (Weiqing Min, Zhiling Wang, Yuxin Liu, Mengjiang Luo, Liping Kang, Xiaom…...

RAN-in-the-Cloud:为 5G RAN 提供云经济性

RAN-in-the-Cloud:为 5G RAN 提供云经济性 5G 部署在全球范围内一直在加速。 许多电信运营商已经推出了5G服务并正在快速扩张。 除了电信运营商之外,企业也对使用 5G 建立私有网络产生了浓厚的兴趣,这些私有网络利用了更高的带宽、更低的延迟…...

vector、list、queue

引用:windows程序员面试指南 vector vector 类似于C语言中的数组 vector 支持随机访问,访问某个元素的时间复杂度 O(1) vector 插入和删除元素效率较低,时间复杂度O(n) vector 是连续存储,没有内存碎片,空间利用率高…...

操作系统面经

进程与线程区别 1.进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位) 2.进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数…...

一天约了4个面试,复盘一下面试题和薪资福利

除了最新的面经分享,还有字节大佬的求职面试答疑,告诉你关键问题是什么?少走弯路。**另外本文也汇总了6份大厂面试题:字节、腾讯、小米、腾讯云、滴滴、小米游戏。**希望对大家有帮助。 前言 昨天我的交流群里,有位宝…...

详解单链表(内有精美图示哦)

全文目录引言链表链表的定义与结构链表的分类单链表的实现及对数据的操作单链表的创建与销毁创建销毁单链表的打印单链表的头插与头删头插头删单链表的尾插与尾删尾插尾删单链表的查找单链表在pos位置后插入/删除插入删除单链表在pos位置插入/删除插入删除总结引言 在上一篇文…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...