前端老弟第一次写后端,崩了!

幽默轻松小知识,一起来看看老弟第一次写的后端代码,你觉得如何?

大家好,我是鱼皮,今天分享我的老弟第一次写后端代码时出现的囧事,希望大家引以为戒。

孽起

我的老弟小阿巴,目前大一,自学编程有一段时间了,之前主要以学前端为主,比较好上手。

但这货最近不知道咋回事,一直嚷嚷着要写写后端代码。

我说:你前端才刚学没多久呢,急什么?

小阿巴说:没人比我更懂前端!

好家伙,没想到几日不见,这家伙现在这么骄傲了!那必须得杀杀他的锐气,让他领略一下后端的恐怖。

于是我说:成,正好我最近在开发一个新功能【删除消息】,功能很简单,允许用户删除自己已经阅读过的消息。前端后端都交给你来做,时间也不急,给你两周,拿去练练手,熟悉下项目吧~

没想到小阿巴这狗说:两周?瞧不起谁呢,就这么一个小功能,我 3 天给你搞定!

我大惊:现在的年轻人都这么强了么?行,我等你!

没想到,不到 3 天,小阿巴真的提交了代码,让我们一起来看看他的实现思路和代码吧。

实现思路

功能实现包括前端和后端两部分,分别来思考一下。

前端

要实现用户已读消息删除功能,前端的工作比较简单,添加一个删除按钮,并且给按钮添加一个点击事件,点击后调用后端 消息删除 接口即可。

前端界面

小阿巴写的前端代码:

<!-- 伪代码 -->
<button onClick={doDelete(消息)}>删除</button>
<script>
  // 删除消息
  function doDelete(msg) {
    // 消息 id 存在且为已读
    if(msg.id && msg.isRead) {
      // 调用后端接口
      service.deleteMsgById(msg.id);
    }
  }
</script>

看着好像没啥问题吧,写的还挺工整的,代码规范好评!

再看看后端怎么样。

后端

后端要做的事情就是接受前端发过来的请求,操作数据库,将数据库中指定 id 的消息删除,再返回是否删除成功给前端。

存放消息的数据库

很多编程语言都可以拿来写后端,比如 Java、Go 语言等。但由于小阿巴是第一次做后端,我心疼他,所以让它使用 NodeJS(JavaScript 语法)来写。

看看小阿巴写的后端代码:

// 删除消息接口
// @params msgId 消息 id
function deleteMsgById(msgId) {
  // 调用数据库删除函数,得到结果
  const res = db.deleteById(msgId);
  return res;
}

总共就这么几行代码,简洁清晰,也难怪小阿巴花了 3 天的时间就写出来了。

不知道大家觉得这段代码怎么样,像不像自己第一次写的代码呢?

请大家思考一下,他写的代码有没有什么问题?

分析问题

其实,小阿巴这段代码问题非常大!一旦上线了,后果不堪设想!

主要有三个问题,我把小阿巴叫了过来,要根据问题的严重性从大到小给他盘一盘。

1. 未做校验

我对小阿巴说:再仔细看看你的代码,是不是少了校验逻辑?

小阿巴疑惑:我不是在前端判断消息 id 是否存在、消息是否已读了么?

我:那如果用户不在浏览器里点删除按钮,而是直接请求接口,随便传消息 id 呢?

小阿巴陷入了沉思。

这是第一次写后台的同学经常犯的错误,尤其是前后端都一个人写的时候,以为在前端判断参数是否合法就够了。但其实,恶意用户可不管这么多,他们可以直接用各种工具在浏览器外向你的后端发送请求,随便传一些消息 id,甚至直接遍历可能的 id。如果后端不做校验,一上线,正常用户的消息可能就被删光了!绝对的 最高级事故

小阿巴:没想到这么严重,那我在后台补上对消息状态的校验,好像也不太行吧?毕竟用户可以任意传递请求参数。

我:挺聪明嘛,的确如此,所以我们还要补上对当前登录用户的校验。

完善的代码大致是这样的:

// 删除消息接口
// @params msgId 消息 id
function deleteMsgById(msgId) {
  // 校验参数合法性
  if (!mgsId) {
    return false;
  }
  // 从数据库查消息最新状态
  const msg = db.getMsgById(msgId);
  // 从 session 或中间件获取当前用户信息
  const user = getCurrentUser();
  // 消息未读或不是该用户的消息
  if (!msg.isRead || !user || msg.userId !== user.id) {
    return false;
  }
  // 调用数据库删除函数,得到结果
  return db.deleteById(msgId);
}

小阿巴:我记住啦,后端接口是业务核心,一定要加强校验!

我:不错,来看看其他的问题吧。

2. 硬删除

我:在你的代码中,直接调用了 delete 函数直接删除数据,你知道这会有什么问题么?

小阿巴:有啥问题?

我:直接删除数据,会导致管理员在需要排查问题时缺少线索。比如用户发送过违规消息,一段之间后把消息自己删掉了,那管理员也不能查出他的违规记录了。

小阿巴:还真是,那咋办?这数据不能删?

我:一般会采用 软删除,给数据表添加一个额外的字段来表示删除状态,比如 isDelete,状态为 0 表示未删除,为 1 表示已删除。正常情况下,只给用户展示 isDelete = 0 的数据,删除时,将该字段的值从 0 更新为 1 即可。

所以上述代码的最后那部分,可以略作修改:

// 原代码,真实删除
db.deleteById(msgId)
// 新代码,软删除(更新)
db.updateById(msgId, {isDelete: 1})

这样后端代码就基本完善了。

当然,也不是所有的数据表都需要软删除,要根据业务场景来决定。

3. 无防误触

最后还有一个产品体验上的小问题,建议在用户点击删除时,出一个二次确认的弹框,否则用户不小心点错了,想找却又找不回消息,那就会感到愤怒了!

确认删除

前端开发做的越多,就会越注重这些小细节,提升用户体验非常重要!


小阿巴:学到了,学到了!我好菜啊 555。

我:没事,这是很正常的,知错能改,就还是好阿巴。

很多正在阅读文章的朋友们,是否也犯过这些小错误呢?请养成良好的编程习惯,多多检查自己的代码吧!

对了,听说点个 ,印象更深刻!

#前端开发##前端##学习路径#
全部评论
这是高手
1 回复 分享
发布于 2021-05-15 23:14
可以的,学到了
点赞 回复 分享
发布于 2021-05-15 14:07
感谢参与【创作者计划3期·技术干货场】!欢迎更多牛油来写干货,瓜分总计20000元奖励!!技术干货场活动链接:https://www.nowcoder.com/link/czz3jsgh3(参与奖马克杯将于每周五结算,敬请期待~)
点赞 回复 分享
发布于 2021-05-28 11:51

相关推荐

纯手码,望见谅:👥&nbsp;面试题目拷打项目,布隆过滤器的底层原理,如何控制长度。底层是如何控制长度的?如何控制误差?扩容因子是多少?订单延迟取消队列是如何设计的。死信队列交换机。java集合,你了解的集合有哪些?synchronized的底层原理。和reentrantlock的区别java设计模式拷打。说说项目中用到了哪些设计模式。spring中哪些功能用到了模板设计模式。如何实习mysql主从,Mysql主从如何设计调优。MVCC底层。当时想提项目用到了canal伪装成mysql的子节点来实现mysql和redis的最终一致性。过于紧张就忘了。如果要实现一个LRU,如何实现?我提到可以直接继承LinkedHashMap.怎么实现的。我说各个方法分别super基础父类。继续深挖,问put的值值存储在哪?TCP的三次和四次。JVM&nbsp;内存结构,垃圾回收。操作系统的内存管理方式。二、滴滴2025届校招正式启动啦!🚘岗位类别工程类/算法类/机器人类/数据类/安全技术类/产品类/运营类/职能类等🚘投递要求2024年9月~2025年8月之间毕业的海内外高校毕业生,每人可投递1个岗位🚘工作地点北京/杭州/上海/广州等🚘招聘流程简历投递-简历筛选-笔试-面试-Offer发放三、面试预约:滴滴面试采用预约制,因为面试的候选人比较多,收到面试预约邮件后尽早选择合适的面试时间,面试席位预约满后会提前关闭,就约不上啦,如果已经招到了合适的候选人,后续就不一定再约面试了,所以一定要尽早选择面试时间,如果没有什么特别的事,也尽量不要修改面试时间四、竞争比较小,进面概率较高岗位:去年秋招是前端,算法,客户端,比较卷的岗位:后端,各个大厂后端简历量都比较多,安排起来就会比较慢,大家耐心等待吧,也可以考虑投一下客户端公司福利薪资在大厂中也算是比较有竞争力的,节假日各种礼包,桔厂周边,校招礼包,司庆礼盒少不了,速来来解锁,小零食,免费晚饭🚘投递方式 内推链接:https://app.mokahr.com/m/campus_apply/didiglobal/96064?recommendCode=DSJUY6Cw&amp;hash=%23%2Fjobs#/jobs内推码:DSJUY6Cw立刻投递,快人一步,抢跑未来!投递后可评论留言姓名缩写+岗位(ljh+研发),后台跟进,能捞就捞
滴滴
|
校招
|
82个岗位
点赞 评论 收藏
分享
评论
7
4
分享
牛客网
牛客企业服务