最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端老弟第一次写后端,崩了!

    正文概述 掘金(程序员鱼皮)   2021-05-19   595

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

    孽起

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

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

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

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

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

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

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

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

    没想到小阿巴这狗说:两周?瞧不起谁呢,就这么一个小功能,我 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。

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

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

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

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

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


    起源地下载网 » 前端老弟第一次写后端,崩了!

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元