Vue3+TS+Node打造个人博客,前端开发交流

dbService.getConnection(function (connection) {

req.connection = connection;

next();

}, function (err) {

return res.send({

…errcode.DB.CONNECT_EXCEPTION

});

})

业务处直接从req获取到connection对象:

router.get(‘/page’, function (req, res, next) {

const connection = req.connection;

const pageNo = Number(req.query.pageNo || 1);

const pageSize = Number(req.query.pageSize || 10);

connection.query(indexSQL.GetPagedArticle, [(pageNo - 1) * pageSize, pageSize], function (error, results, fileds) {

connection.release();

// 其他业务代码

})

SQL 语句主要是以字符串的形式编写,通过?作为一个参数槽位,接收一些动态的值。

比如一个逻辑删除的语句,我们会这样写:

// 逻辑删除/恢复

UpdateArticleDeleted: ‘UPDATE article SET deleted = ? WHERE id = ?’,

第一个?是留给字段deleted的值,第二个?便是传具体的id值。

而参数传值是通过connection.query的第二个参数携带的。

注意,这个参数是一个数组,数组中的值会按照从左到右的顺序依次替换掉 SQL 字符串中的?,变成一个真实的可执行的 SQL 语句。

connection.query(indexSQL.UpdateArticleDeleted, [params.deleted, params.id], function (error, results, fileds) {})

connection.query执行回调后切记调用connection.release释放连接。

另外要注意的一个就是 MySQL 的事务处理。对事务而言,初步要关注的是这三个 API!具体的使用场景我在后面的具体应用会再提到,这里就不展开了!

// 开始事务,对应 MySQL begin 语句

connection.beginTransaction();

// 事务提交,对应 MySQL commit 语句

connection.commit();

// 事务回滚,对应 MySQL rollback 语句

connection.rollback();

20220218更新


为了保留在这个项目中我使用mysql思路的一个转变过程,前面的 mysql 调用过程,我还是按照最初的想法展开介绍的,关键的也就是这么几点。

  1. BaseController 统一获取 mysql pool 的 connection 对象,并挂载到 req 对象上,供后面的业务使用。

  2. 业务 Controller 与 mysql 交互时,只需要从 req 对象中取得 connection,通过 connection.query 去执行 sql 语句。

  3. 业务 Controller 执行完 sql 语句后,主动 release 释放掉 connection。

  4. 事务场景中,事务处理完毕后,统一 release 释放掉 connection,而不是每个 query 都自行释放 connection。

这样的设计,虽然省去了在具体业务 Controller 执行getConnection(少一层回调写法),但是在connection.release()的把控上还存在漏洞,一旦业务调用方忘记调用release(),就有可能造成服务不可用。而且有的业务不需要与 mysql 交互,也必须要记得 release(),虽然可以用一些配置字段去规避,也并不能从根本上解决问题!

所以我的修改方案是:

  1. 总体的原则是高内聚,低耦合

  2. 封装 mysql 的查询过程,把 getConnection, query, release 等几个关键行为都放在封装的代码中控制,对外只暴露一些封装好的方法,这样就不用担心调用方忘记某些关键操作(比如release())。

  3. 关键 API Promise 化,这样在一些复杂的异步过程中可以做到事半功倍,特别是涉及事务处理的时候!

核心代码见db.js[5]

响应返回体

=====

响应返回体的数据结构是需要前后端进行约定的,只有约定好规范,双方才能紧密有序地配合起来。通常来说,会涉及到错误码,信息,数据等字段。

其中错误码code,信息message两个字段应该是通用的。数据部分data则随业务的需要,可能会有多种情况,比如数组结构,对象结构,或者是普通数据类型。

{

code: “0”,

message: “查询成功”,

data: {

id: 1,

name: ‘xxx’

}

}

错误码

===

错误码是后端规范中必不可少的部分。错误码的设计是为了快速定位问题,也为一些业务监控系统提供了分析和统计依据。

每个程序员会有自己的一些编码风格,在错误码这块,我是通过语义化的属性名去定位到错误码的。通常,一个错误码会配对一条错误信息,也就是下面的msg字段。

module.exports = {

DB: {

CONNECT_EXCEPTION: {

code: “-1”,

msg: “数据库连接异常”

}

},

AUTH: {

UNAUTHORIZED: {

code: “000001”,

msg: “对不起,您还未获得授权”

},

AUTHORIZE_EXPIRED: {

code: “000002”,

msg: “授权已过期”

},

FORBIDDEN: {

code: “000003”,

msg: “抱歉,您没有权限访问该内容”

}

},

}

错误码的设计还有一个好处,就是方便做映射

什么意思呢?后端返回错误码-1,并且通过msg字段告诉前端错误信息是数据库连接异常。但是,前端到底要不要反馈用户这么直接粗暴的信息呢?我想,有时候是不需要的,而是通过一条委婉的提示来安抚一下用户情绪

比如,

8492f75d4d1c03a46489a16f437e40a3.png

所以,有了错误码,前端就可以收放自如,在错误提示上有更多发挥的余地,而不是直白地把后端反馈的错误信息直接暴露给用户。

简单的一个映射可以是:

// ERR_MSG

{

“-1”: “系统开了个小差,请稍后重试!”,

}

那么message的展示逻辑就可以是:

message.error(ERR_MSG[res.code])

Web安全

=====

主要是考虑几个方面,XSS,CSRF,响应头。

XSS,指的是 Cross-Site-Scripting 跨站脚本攻击。出现 XSS 漏洞的主要场景是用户输入,比如评论,富文本等信息,如果不加以校验,就可能会被植入恶意代码,造成数据和财产损失!

针对 XSS 的校验不能光靠客户端,服务端也必须进行校验。我这里用的是xss@1.0.9

npm install --save xss

xss默认会处理掉常见的 XSS 风险,使用起来也非常简单。比如,在新增评论的接口处,我们可以对参数这样处理:

const xss = require(“xss”);

router.post(‘/add’, function (req, res, next) {

const params = Object.assign(req.body, {

create_time: new Date(),

});

// XSS防护

if (params.content) {

params.content = xss(params.content)

}

}

虽然我目前还没有用富文本承载评论内容,但是还是先预备一下,万一哪天想用富文本了呢!

至于 CSRF(跨站请求伪造)攻击,常见的漏洞来源就是基于 Cookie 的身份验证,因为 Cookie 会在发 HTTP 请求的时候自动带上,这样一来攻击者就有了可乘之机,通过脚本注入,或者一些引诱点击,让你不知不觉就上了套,发出了意料之外的请求。

不过,浏览器也是在不断完善 Cookie 安全这块,比如 Chrome 80 版本默认启用的 SameSite=Lax,也防范了很多 CSRF 的攻击场景。

为了安全起见,在 Set-Cookie 时,最好带上这些属性。

Set-Cookie: token=74afes7a8; HttpOnly; Secure; SameSite=Lax;

为了防止 CSRF 攻击,还可以采用 csrf-token 方式,或者采用 JWT 认证,共同点都是避开基于 Cookie 的身份/口令认证方式。

另外,设置一些必要的响应头对于 Web 安全也至关重要!

Express 推荐我们直接用上helmet

Helmet 通过设置各种 HTTP 请求头,提升 Express 应用的安全性。它不是 Web 安全的银弹,但的确有所帮助!

安装helmet

npm install --save helmet

使用起来也很简单,因为它就是一个中间件。

app.use(helmet());

ad715b1ea04d28008aae07cc3d240a2d.png

环境变量/配置

=======

由于后端配置文件中一般会出现一些私密性的配置,比如数据库配置,服务器配置,这些都不适合在开源项目中直接出现。所以,在本项目[6]中,我只给出了example示例,大家按照说明给出自己的配置文件即可。

  • 通用配置:config/env.example.js

  • 开发环境配置:config/dev.env.example.js

  • 生产环境配置:config/prod.env.example.js

  • PM2 deploy 配置:deploy.config.example.js

数据库、邮箱配置,以及其他的参数配置,建议是给开发环境和生产环境单独配置,避免本地开发时直接影响到生产环境。

所以,我们需要设置环境标识,并且根据环境标识来引用对应的参数配置。

环境标识我们都不陌生了,它就是process.env.NODE_ENV。由于项目中用到了pm2,所以我是通过pm2来配置NODE_ENV的。

env: {

NODE_ENV: “development”,

PORT: 8002,

},

env_production: {

NODE_ENV: ‘production’,

PORT: 8002,

},

所以,我们只要根据NODE_ENV来判断开发环境或生产环境,然后加载对应的参数配置即可。逻辑非常简单!

// 配置入口文件,根据环境标识导出配置

const baseEnv = require(“./env”)

const devEnv = require(“./dev.env”)

const prodEnv = require(“./prod.env”)

module.exports = process.env.NODE_ENV === ‘production’ ? {

…baseEnv,

…prodEnv

} : {

…baseEnv,

…devEnv

}

小结

==

本文是Vue3+TS+Node打造个人博客(后端架构篇),从一个不太专业的视角来切入后端,主要介绍了我在为博客系统设计后端时的一些主要思路,诸多细节不便展开,可以打开源码[7]了解。

有了这次全栈开发的经验,大大提高了我对前后端全链路的理解程度,这之后和后端开发们聊天也更有话题可聊了,有时候还能帮后端捋捋思路、一起排查下问题。总之非常奈斯!

但是,要把后端做完善还有很多的路要走,看看 Java 那么多中间件就知道了,道阻且长,行则将至,加油吧!

b3a94fbe1743551a3a76ad41ff061908.png

系列文章

====

Vue3+TS+Node打造个人博客系列文章入口可点击下方链接,持续更新,欢迎阅读!点赞关注不迷路!😍

  • Vue3+TS+Node打造个人博客(总览篇)[8]

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

最后

基础知识是前端一面必问的,如果你在基础知识这一块翻车了,就算你框架玩的再6,webpack、git、node学习的再好也无济于事,因为对方就不会再给你展示的机会,千万不要因为基础错过了自己心怡的公司。前端的基础知识杂且多,并不是理解就ok了,有些是真的要去记。当然了我们是牛x的前端工程师,每天像背英语单词一样去背知识点就没必要了,只要平时工作中多注意总结,面试前端刷下题目就可以了。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-AwSeNDHR-1712706985968)]

最后

基础知识是前端一面必问的,如果你在基础知识这一块翻车了,就算你框架玩的再6,webpack、git、node学习的再好也无济于事,因为对方就不会再给你展示的机会,千万不要因为基础错过了自己心怡的公司。前端的基础知识杂且多,并不是理解就ok了,有些是真的要去记。当然了我们是牛x的前端工程师,每天像背英语单词一样去背知识点就没必要了,只要平时工作中多注意总结,面试前端刷下题目就可以了。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-2290uWMf-1712706985968)]

要开发一个基于Vue3、TypeScript、Node和MySQL的个人博客,可以参考以下步骤: 1. 首先,你可以参考中的文章,了解如何使用Vue3和TypeScript搭建前端界面。这篇文章提供了一个非常详细的总览,包括项目的结构和要点。 2. 接下来,你可以在GitHub上找到一个示例项目,该项目是基于Vue3和TypeScript的前端博客部分。你可以根据该项目的结构和代码实现自己的个人博客前端。 3. 对于后端部分,你可以使用Node.js和Express框架来搭建一个RESTful API。你可以参考中的示例项目,该项目提供了一个使用Express和MySQL构建的简单博客后端。你可以根据该项目的结构和代码实现自己的个人博客后端。 4. 在数据库方面,你可以使用MySQL作为存储数据的后端。你可以根据个人博客的需求设计数据库表结构,并使用Node.js和MySQL连接库来实现数据的增删改查等操作。 综上所述,你可以通过使用Vue3、TypeScript、Node和MySQL来开发个人博客。首先搭建前端界面,然后使用Node和Express搭建后端API,并使用MySQL作为数据库存储数据。通过参考、和中的文章和示例项目,你可以更好地理解和实现这个过程。祝你成功!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue3+TS+Node打造个人博客(后端架构)](https://blog.csdn.net/weixin_41196185/article/details/123415200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值