<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 3558字,需瀏覽 8分鐘

           ·

          2021-06-05 11:06

          留言有禮:小編每天會在文章留言中隨機(jī)抽取走心留言贈送現(xiàn)金紅包


          幽默輕松小知識,一起來看看老弟第一次寫的后端代碼,你覺得如何?


          大家好,今天分享我的老弟第一次寫后端代碼時出現(xiàn)的囧事,希望大家引以為戒。

          孽起

          我的老弟小阿巴,目前大一,自學(xué)編程有一段時間了,之前主要以學(xué)前端為主,比較好上手。

          但這貨最近不知道咋回事,一直嚷嚷著要寫寫后端代碼。

          我說:你前端才剛學(xué)沒多久呢,急什么?

          小阿巴說:沒人比我更懂前端!

          好家伙,沒想到幾日不見,這家伙現(xiàn)在這么驕傲了!那必須得殺殺他的銳氣,讓他領(lǐng)略一下后端的恐怖。

          于是我說:成,正好我最近在開發(fā)一個新功能【刪除消息】,功能很簡單,允許用戶刪除自己已經(jīng)閱讀過的消息。前端后端都交給你來做,時間也不急,給你兩周,拿去練練手,熟悉下項目吧~

          沒想到小阿巴這狗說:兩周?瞧不起誰呢,就這么一個小功能,我 3 天給你搞定!

          我大驚:現(xiàn)在的年輕人都這么強(qiáng)了么?行,我等你!

          沒想到,不到 3 天,小阿巴真的提交了代碼,讓我們一起來看看他的實現(xiàn)思路和代碼吧。

          實現(xiàn)思路

          功能實現(xiàn)包括前端和后端兩部分,分別來思考一下。

          前端

          要實現(xiàn)用戶已讀消息刪除功能,前端的工作比較簡單,添加一個刪除按鈕,并且給按鈕添加一個點擊事件,點擊后調(diào)用后端 消息刪除 接口即可。

          前端界面

          小阿巴寫的前端代碼:

          <!-- 偽代碼 -->
          <button onClick={doDelete(消息)}>刪除</button>
          <script>
            // 刪除消息
            function doDelete(msg{
              // 消息 id 存在且為已讀
              if(msg.id && msg.isRead) {
                // 調(diào)用后端接口
                service.deleteMsgById(msg.id);
              }
            }
          </script>

          看著好像沒啥問題吧,寫的還挺工整的,代碼規(guī)范好評!

          再看看后端怎么樣。

          后端

          后端要做的事情就是接受前端發(fā)過來的請求,操作數(shù)據(jù)庫,將數(shù)據(jù)庫中指定 id 的消息刪除,再返回是否刪除成功給前端。

          存放消息的數(shù)據(jù)庫

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

          看看小阿巴寫的后端代碼:

          // 刪除消息接口
          // @params msgId 消息 id
          function deleteMsgById(msgId{
            // 調(diào)用數(shù)據(jù)庫刪除函數(shù),得到結(jié)果
            const res = db.deleteById(msgId);
            return res;
          }

          總共就這么幾行代碼,簡潔清晰,也難怪小阿巴花了 3 天的時間就寫出來了。

          不知道大家覺得這段代碼怎么樣,像不像自己第一次寫的代碼呢?

          請大家思考一下,他寫的代碼有沒有什么問題?

          分析問題

          其實,小阿巴這段代碼問題非常大!一旦上線了,后果不堪設(shè)想!

          主要有三個問題,我把小阿巴叫了過來,要根據(jù)問題的嚴(yán)重性從大到小給他盤一盤。

          1. 未做校驗

          我對小阿巴說:再仔細(xì)看看你的代碼,是不是少了校驗邏輯?

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

          我:那如果用戶不在瀏覽器里點刪除按鈕,而是直接請求接口,隨便傳消息 id 呢?

          小阿巴陷入了沉思。

          這是第一次寫后臺的同學(xué)經(jīng)常犯的錯誤,尤其是前后端都一個人寫的時候,以為在前端判斷參數(shù)是否合法就夠了。但其實,惡意用戶可不管這么多,他們可以直接用各種工具在瀏覽器外向你的后端發(fā)送請求,隨便傳一些消息 id,甚至直接遍歷可能的 id。如果后端不做校驗,一上線,正常用戶的消息可能就被刪光了!絕對的 最高級事故

          小阿巴:沒想到這么嚴(yán)重,那我在后臺補(bǔ)上對消息狀態(tài)的校驗,好像也不太行吧?畢竟用戶可以任意傳遞請求參數(shù)。

          我:挺聰明嘛,的確如此,所以我們還要補(bǔ)上對當(dāng)前登錄用戶的校驗。

          完善的代碼大致是這樣的:

          // 刪除消息接口
          // @params msgId 消息 id
          function deleteMsgById(msgId{
            // 校驗參數(shù)合法性
            if (!mgsId) {
              return false;
            }
            // 從數(shù)據(jù)庫查消息最新狀態(tài)
            const msg = db.getMsgById(msgId);
            // 從 session 或中間件獲取當(dāng)前用戶信息
            const user = getCurrentUser();
            // 消息未讀或不是該用戶的消息
            if (!msg.isRead || !user || msg.userId !== user.id) {
              return false;
            }
            // 調(diào)用數(shù)據(jù)庫刪除函數(shù),得到結(jié)果
            return db.deleteById(msgId);
          }

          小阿巴:我記住啦,后端接口是業(yè)務(wù)核心,一定要加強(qiáng)校驗!

          我:不錯,來看看其他的問題吧。

          2. 硬刪除

          我:在你的代碼中,直接調(diào)用了 delete 函數(shù)直接刪除數(shù)據(jù),你知道這會有什么問題么?

          小阿巴:有啥問題?

          我:直接刪除數(shù)據(jù),會導(dǎo)致管理員在需要排查問題時缺少線索。比如用戶發(fā)送過違規(guī)消息,一段之間后把消息自己刪掉了,那管理員也不能查出他的違規(guī)記錄了。

          小阿巴:還真是,那咋辦?這數(shù)據(jù)不能刪?

          我:一般會采用 軟刪除,給數(shù)據(jù)表添加一個額外的字段來表示刪除狀態(tài),比如 isDelete,狀態(tài)為 0 表示未刪除,為 1 表示已刪除。正常情況下,只給用戶展示 isDelete = 0 的數(shù)據(jù),刪除時,將該字段的值從 0 更新為 1 即可。

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

          // 原代碼,真實刪除
          db.deleteById(msgId)
          // 新代碼,軟刪除(更新)
          db.updateById(msgId, {isDelete1})

          這樣后端代碼就基本完善了。

          當(dāng)然,也不是所有的數(shù)據(jù)表都需要軟刪除,要根據(jù)業(yè)務(wù)場景來決定。

          3. 無防誤觸

          最后還有一個產(chǎn)品體驗上的小問題,建議在用戶點擊刪除時,出一個二次確認(rèn)的彈框,否則用戶不小心點錯了,想找卻又找不回消息,那就會感到憤怒了!

          確認(rèn)刪除

          前端開發(fā)做的越多,就會越注重這些小細(xì)節(jié),提升用戶體驗非常重要!




          小阿巴:學(xué)到了,學(xué)到了!我好菜啊 555。

          我:沒事,這是很正常的,知錯能改,就還是好阿巴。

          很多正在閱讀文章的朋友們,是否也犯過這些小錯誤呢?請養(yǎng)成良好的編程習(xí)慣,多多檢查自己的代碼吧!


          往期推薦


          又一程序員刪庫跑路被判刑,原因是離職后討薪?(留言送書)

          2021-05-29

          計算機(jī)女神,互聯(lián)網(wǎng)第一夫人!

          2021-05-29

          鴻蒙手機(jī)來了!

          2021-05-28

          Python之父:Python 4.0可能不會來了

          2021-05-27



          今天因為您的點贊和在看,讓我元氣滿滿!
          瀏覽 69
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  丁香色情五月综合网站 | 欧美性爱国产乱伦 | 亚洲成人第一页 | 玖玖视频在线免费观看 | 九九九精品在线 |