分享一次 JS 代碼閱讀的笨方法

来源:http://www.cnblogs.com/InformationGod/archive/2017/08/04/7285187.html
-Advertisement-
Play Games

一直在寫伺服器端,最近在用Netty-NIO編寫聊天。web端用JS實現聊天界面……js用得不多,於是下了一個仿微信的JS Demo。裡面用到了vue.js庫。 殘忍的源碼: 大概600行,但是對於我這個菜鳥來說,過多的了。 代碼裡面沒註釋,名稱寫得也非常亂(單個字母為主,太恐怖了。。。),又沒接觸 ...


        一直在寫伺服器端,最近在用Netty-NIO編寫聊天。web端用JS實現聊天界面……js用得不多,於是下了一個仿微信的JS Demo。裡面用到了vue.js庫

 

  殘忍的源碼

  大概600行,但是對於我這個菜鳥來說,過多的了。

  代碼裡面沒註釋,名稱寫得也非常亂(單個字母為主,太恐怖了。。。),又沒接觸過 Vue.js,只最近幾天看了點vue的官方文檔,高階的沒時間一下子啃下來。

 

  我的問題是:

  不知道 main.js 中代碼的執行順序,它內部怎麼跑起來的。

 

  Demo里的結構是這樣的:

  

  界面效果是這樣的:

  

 

  Vue.js是庫,index.html文件最重要的只有一行代碼:

<div id="chat"></div>

  然後最重要的是 main.js代碼了,不知道哪位大神寫的,讀了好久理不清頭緒,不知道JS從哪開始執行的……

  附上 main.js 源碼

  1 ! function(e) {//e=18行以後的全部函數。 為什麼會這樣呢?
  2     console.log("e");
  3     function t(r) {
  4     console.log("e-00");
  5         if(s[r]) return s[r].exports;
  6         var i = s[r] = {
  7             exports: {},//輸出HTML內容
  8             id: r,
  9             loaded: !1
 10         };
 11         console.log("函數  e-00  執行完了");
 12         return e[r].call(i.exports, i, i.exports, t), i.loaded = !0, i.exports
 13     }
 14     var s = {};
 15     console.log("函數 e 執行完了");
 16     return t.m = e, t.c = s, t.p = "/dist/", t(0)
 17 }
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 ([
 26 
 27 function(e, t, s) {
 28     console.log("[2-1]");
 29     "use strict";
 30 
 31     function r(e) {
 32     console.log("[2-1-00]");
 33         return e && e.__esModule ? e : {
 34             "default": e
 35         }
 36     }
 37     var i = s(32),
 38         o = r(i);
 39     Vue.config.debug = !0, new Vue(o["default"])
 40     console.log("函數[2-1]執行完了");
 41 }
 42 
 43 
 44 , function(e, t) {
 45     console.log("[2-2]");
 46     e.exports = function() {
 47     console.log("[2-2-01]");
 48         var e = [];
 49         return e.toString = function() {
 50             console.log("[2-2-02]");
 51             for(var e = [], t = 0; t < this.length; t++) {
 52                 var s = this[t];
 53                 s[2] ? e.push("@media " + s[2] + "{" + s[1] + "}") : e.push(s[1])
 54             }
 55             return e.join("")
 56         }, e.i = function(t, s) {
 57             "string" == typeof t && (t = [
 58                 [null, t, ""]
 59             ]);
 60             for(var r = {}, i = 0; i < this.length; i++) {
 61                 var o = this[i][0];
 62                 "number" == typeof o && (r[o] = !0)
 63             }
 64             for(i = 0; i < t.length; i++) {
 65                 var n = t[i];
 66                 "number" == typeof n[0] && r[n[0]] || (s && !n[2] ? n[2] = s : s && (n[2] = "(" + n[2] + ") and (" + s + ")"), e.push(n))
 67             }
 68         }, e
 69     }
 70 }
 71 
 72 
 73 , function(e, t, s) {
 74     console.log("[2-3]");
 75     function r(e, t) {
 76     console.log("[2-3-1]");
 77         for(var s = 0; s < e.length; s++) {
 78             var r = e[s],
 79                 i = d[r.id];
 80             if(i) {
 81                 i.refs++;
 82                 for(var o = 0; o < i.parts.length; o++) i.parts[o](r.parts[o]);
 83                 for(; o < r.parts.length; o++) i.parts.push(a(r.parts[o], t))
 84             } else {
 85                 for(var n = [], o = 0; o < r.parts.length; o++) n.push(a(r.parts[o], t));
 86                 d[r.id] = {
 87                     id: r.id,
 88                     refs: 1,
 89                     parts: n
 90                 }
 91             }
 92         }
 93     }
 94 
 95     function i(e) {        
 96     console.log("[2-3-2]");
 97         for(var t = [], s = {}, r = 0; r < e.length; r++) {
 98             var i = e[r],
 99                 o = i[0],
100                 n = i[1],
101                 a = i[2],
102                 l = i[3],
103                 c = {
104                     css: n,
105                     media: a,
106                     sourceMap: l
107                 };
108             s[o] ? s[o].parts.push(c) : t.push(s[o] = {
109                 id: o,
110                 parts: [c]
111             })
112         }
113         return t
114     }
115 
116     function o() {        
117         console.log("[2-3-3]");
118         var e = document.createElement("style"),
119             t = m();
120         return e.type = "text/css", t.appendChild(e), e
121     }
122 
123     function n() {
124         console.log("[2-3-4]");
125         var e = document.createElement("link"),
126             t = m();
127         return e.rel = "stylesheet", t.appendChild(e), e
128     }
129 
130     function a(e, t) {
131         console.log("[2-3-5]");
132         var s, r, i;
133         if(t.singleton) {
134             var a = x++;
135             s = h || (h = o()), r = l.bind(null, s, a, !1), i = l.bind(null, s, a, !0)
136         } else e.sourceMap && "function" == typeof URL && "function" == typeof URL.createObjectURL && "function" == typeof URL.revokeObjectURL && "function" == typeof Blob && "function" == typeof btoa ? (s = n(), r = u.bind(null, s), i = function() {
137             s.parentNode.removeChild(s), s.href && URL.revokeObjectURL(s.href)
138         }) : (s = o(), r = c.bind(null, s), i = function() {
139             s.parentNode.removeChild(s)
140         });
141         return r(e),
142             function(t) {
143                 if(t) {
144                     if(t.css === e.css && t.media === e.media && t.sourceMap === e.sourceMap) return;
145                     r(e = t)
146                 } else i()
147             }
148     }
149 
150     function l(e, t, s, r) {
151         console.log("[2-3-6]");
152         var i = s ? "" : r.css;
153         if(e.styleSheet) e.styleSheet.cssText = g(t, i);
154         else {
155             var o = document.createTextNode(i),
156                 n = e.childNodes;
157             n[t] && e.removeChild(n[t]), n.length ? e.insertBefore(o, n[t]) : e.appendChild(o)
158         }
159     }
160 
161     function c(e, t) {
162         console.log("[2-3-7]");
163         var s = t.css,
164             r = t.media;
165         t.sourceMap;
166         if(r && e.setAttribute("media", r), e.styleSheet) e.styleSheet.cssText = s;
167         else {
168             for(; e.firstChild;) e.removeChild(e.firstChild);
169             e.appendChild(document.createTextNode(s))
170         }
171     }
172 
173     function u(e, t) {
174         console.log("[2-3-8]");
175         var s = t.css,
176             r = (t.media, t.sourceMap);
177         r && (s += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(r)))) + " */");
178         var i = new Blob([s], {
179                 type: "text/css"
180             }),
181             o = e.href;
182         e.href = URL.createObjectURL(i), o && URL.revokeObjectURL(o)
183     }
184     var d = {},
185         p = function(e) {
186             var t;
187             return function() {
188                 return "undefined" == typeof t && (t = e.apply(this, arguments)), t
189             }
190         },
191         f = p(function() {
192             return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())
193         }),
194         m = p(function() {
195             return document.head || document.getElementsByTagName("head")[0]
196         }),
197         h = null,
198         x = 0;
199     e.exports = function(e, t) {
200         t = t || {}, "undefined" == typeof t.singleton && (t.singleton = f());
201         var s = i(e);
202         return r(s, t),
203             function(e) {
204                 for(var o = [], n = 0; n < s.length; n++) {
205                     var a = s[n],
206                         l = d[a.id];
207                     l.refs--, o.push(l)
208                 }
209                 if(e) {
210                     var c = i(e);
211                     r(c, t)
212                 }
213                 for(var n = 0; n < o.length; n++) {
214                     var l = o[n];
215                     if(0 === l.refs) {
216                         for(var u = 0; u < l.parts.length; u++) l.parts[u]();
217                         delete d[l.id]
218                     }
219                 }
220             }
221     };
222     var g = function() {
223         var e = [];
224         return function(t, s) {
225             return e[t] = s, e.filter(Boolean).join("\n")
226         }
227     }()
228 }, , , , , , function(e, t, s) {
229     "use strict";
230 
231     function r(e) {
232         console.log("[2-3-9]");
233         return e && e.__esModule ? e : {
234             "default": e
235         }
236     }
237     Object.defineProperty(t, "__esModule", {
238         value: !0
239     });
240     var i = s(13),
241         o = r(i),
242         n = s(33),
243         a = r(n),
244         l = s(34),
245         c = r(l),
246         u = s(36),
247         d = r(u),
248         p = s(35),
249         f = r(p);
250     t["default"] = {
251         el: "#chat",
252         data: function() {
253             var e = o["default"].fetch();
254             return {
255                 user: e.user,
256                 userList: e.userList,
257                 sessionList: e.sessionList,
258                 search: "",
259                 sessionIndex: 0
260             }
261         },
262         computed: {
263             session: function() {
264                 return this.sessionList[this.sessionIndex]
265             }
266         },
267         watch: {
268             sessionList: {
269                 deep: !0,
270                 handler: function() {
271                     o["default"].save({
272                         user: this.user,
273                         userList: this.userList,
274                         sessionList: this.sessionList
275                     })
276                 }
277             }
278         },
279         components: {
280             card: a["default"],
281             list: c["default"],
282             text: d["default"],
283             message: f["default"]
284         }
285     }
286 }
287 
288 , function(e, t) {
289         console.log("[2-3-10]");
290     "use strict";
291     Object.defineProperty(t, "__esModule", {
292         value: !0
293     }), t["default"] = {
294         props: ["user", "search"]
295     }
296 }
297 
298 , function(e, t) {
299         console.log("[2-3-11]");
300     "use strict";
301     Object.defineProperty(t, "__esModule", {
302         value: !0
303     }), t["default"] = {
304         props: ["userList", "sessionIndex", "session", "search"],
305         methods: {
306             select: function(e) {
307                 this.sessionIndex = this.userList.indexOf(e)
308             }
309         },
310         filters: {
311             search: function(e) {
312                 var t = this;
313                 return e.filter(function(e) {
314                     return e.name.indexOf(t.search) > -1
315                 })
316             }
317         }
318     }
319 }
320 
321 , function(e, t) {
322         console.log("[2-3-12]");
323     "use strict";
324     Object.defineProperty(t, "__esModule", {//定義屬性
325         value: !0
326     }), t["default"] = {
327         props: ["session", "user", "userList"],
328         computed: {//實例被創建之後調用
329             sessionUser: function() {
330                 var e = this,
331                     t = this.userList.filter(function(t) {
332                         return t.id === e.session.userId
333                     });
334                 return t[0]
335             }
336         },
337         filters: {
338             avatar: function(e) {
339                 var t = e.self ? this.user : this.sessionUser;
340                 return t && t.img
341             },
342             time: function(e) {
343                 return "string" == typeof e && (e = new Date(e)), e.getHours() + ":" + e.getMinutes()
344             }
345         },
346         directives: {//自定義指令:滾動到消息瀑布底部
347             "scroll-bottom": function() {
348                 var e = this;
349                 Vue.nextTick(function() {
350                     e.el.scrollTop = e.el.scrollHeight - e.el.clientHeight
351                 })
352             }
353         }
354     }
355 }
356 
357 , function(e, t) {
358         console.log("[2-3-13]");
359     "use strict";
360     Object.defineProperty(t, "__esModule", {
361         value: !0
362     }), t["default"] = {
363         props: ["session"],
364         data: function() {
365             return {
366                 text: "",
367                 //測試圖片
368                 image:""
369             }
370         },
371         methods: {
372             inputing: function(e) {
373                 13 === e.keyCode && this.text.length && (this.session.messages.push({//e.ctrlKey &&  去掉了 ctrlKey鍵
374                     text: this.text,//消息內容
375                     image:this.image, //測試圖片
376                     date: new Date,//消息發送日期
377                     self: !0//保證信息在自己的聊天視窗中靠近自己的頭像一邊顯示
378                 }), this.text = "")
379             }
380         }
381     }
382 }
383 
384 , function(e, t, s) {
385         console.log("[2-3-14]");
386     "use strict";
387 
388     function r(e) {
389         return e && e.__esModule ? e : {
390             "default": e
391         }
392     }
393     Object.defineProperty(t, "__esModule", {
394         value: !0
395     });
396     var i = s(14),
397         o = r(i),
398         n = "VUE-CHAT-v3";
399     if(!localStorage.getItem(n)) {
400         var a = new Date,
401             l = {
402                 user: {//代表自己
403                     id: 1,
404                     name: "咖啡",
405                     img: "dist/images/1.jpg"
406                 },
407                 userList: [{//類似於好友列表
408                     id: 2,
409                     name: "大神例介紹",
410                     img: "dist/images/2.png"
411                 }, {
412                     id: 3,
413                     name: "webpack",
414                     img: "dist/images/3.jpg"
415                 }],
416                 sessionList: [{//聊天會話列表
417                     userId: 2,
418                     messages: [{
419                         text: "我是大神例介紹,這是一個基於Vue + Webpack構建的簡單chat示例,聊天記錄保存在localStorge。簡單演示了Vue的基礎特性和webpack配置。",
420                         date: a
421                     }, {
422                         text: "項目下載地址1: https://github.com/coffcer/vue-chat",
423                         date: a
424                     }, {
425                         text: "項目下載地址2: https://github.com/coffcer/vue-chat",
426                         date: a
427                     }]
428                 },{//聊天會話列表
429                     userId: 3,
430                     messages: [{
431                         text: "我是wepack,這是一個基於Vue + Webpack構建的簡單chat示例,聊天記錄保存在localStorge。簡單演示了Vue的基礎特性和webpack配置。",
432                         date: a
433                     }, {
434                         text: "項目下載地址1: https://github.com/coffcer/vue-chat",
435                         date: a
436                     }, {
437                         text: "項目下載地址2: https://github.com/coffcer/vue-chat",
438                         date: a
439                     }]
440                 }]
441             };
442         localStorage.setItem(n, (0, o["default"])(l))
443     }
444     t["default"] = {
445         fetch: function() {
446             return JSON.parse(localStorage.getItem(n))
447         },
448         save: function(e) {
449             localStorage.setItem(n, (0, o["default"])(e))
450         }
451     }
452 }
453 
454 , function(e, t, s) {
455         console.log("[2-3-15]");
456     e.exports = {
457         "default": s(15),
458         __esModule: !0
459     }
460 }
461 
462 , function(e, t, s) {
463         console.log("[2-3-16]");
464     var r = s(16);
465     e.exports = function(e) {
466         return(r.JSON && r.JSON.stringify || JSON.stringify).apply(JSON, arguments)
467     }
468 }
469 
470 , function(e, t) {
471         console.log("[2-3-17]");
472     var s = e.exports = {
473         version: "1.2.6"
474     };
475     "number" == typeof __e && (__e = s)
476 }
477 
478 , function(e, t, s) {//消息發送框
479         console.log("消息發送框樣式");
480     t = e.exports = s(1)(), t.push([e.id, ".m-text{height:10pc;border-top:1px solid #ddd}.m-text textarea{padding:10px;height:100%;width:100%;border:none;outline:0;font-family:Micrsofot Yahei;resize:none}", ""])
481 }
482 
483 , function(e, t, s) {//左側用戶狀態信息框
484         console.log("左側用戶狀態信息框樣式");
485     t = e.exports = s(1)(), t.push([e.id, "#chat{overflow:hidden;border-radius:3px}#chat .main,#chat .sidebar{height:100%}#chat .sidebar{float:left;width:200px;color:#f4f4f4;background-color:#2e3238}#chat .main{position:relative;overflow:hidden;background-color:#eee}#chat .m-text{position:absolute;width:100%;bottom:0;left:0}#chat .m-message{height:calc(100% - 10pc)}", ""])
486 }
487 
488 , function(e, t, s) {//查找用戶視窗
489         console.log("查找用戶視窗樣式");
490     t = e.exports = s(1)(), t.push([e.id, ".m-card{padding:9pt;border-bottom:1px solid #24272c}.m-card footer{margin-top:10px}.m-card .avatar,.m-card .name{vertical-align:middle}.m-card .avatar{border-radius:2px}.m-card .name{display:inline-block;margin:0 0 0 15px;font-size:1pc}.m-card .search{padding:0 10px;width:100%;font-size:9pt;color:#fff;height:30px;line-height:30px;border:1px solid #3a3a3a;border-radius:4px;outline:0;background-color:#26292e}", ""])
491 }
492 
493 , function(e, t, s) {//對話用戶列表
494         console.log("對話用戶列表樣式");
495     t = e.exports = s(1)(), t.push([e.id, ".m-list li{padding:9pt 15px;border-bottom:1px solid #292c33;cursor:pointer;-webkit-transition:background-color .1s;transition:background-color .1s}.m-list li:hover{background-color:hsla(0,0%,100%,.03)}.m-list li.active{background-color:hsla(0,0%,100%,.1)}.m-list .avatar,.m-list .name{vertical-align:middle}.m-list .avatar{border-radius:2px}.m-list .name{display:inline-block;margin:0 0 0 15px}", ""])
496 }
497 
498 , function(e, t, s) {//消息對話框
499         console.log("消息對話框樣式");
500     t = e.exports = s(1)(), t.push([e.id, '.m-message{padding:10px 15px;overflow-y:scroll}.m-message li{margin-bottom:20px}.m-message .time{margin:7px 0;text-align:center}.m-message .time>span{display:inline-block;padding:0 18px;font-size:9pt;color:black;border-radius:2px;background-color:#dcdcdc}.m-message .avatar{float:left;margin:0 10px 0 0;border-radius:3px}.m-message .text{display:inline-block;position:relative;padding:0px 10px;max-width:calc(100% - 240px);min-height:30px;line-height:2;font-size:10pt;text-align:left;word-break:break-all;background-color:white;border-radius:4px}.m-message .text:before{content:" ";position:absolute;top:9px;right:100%;border:1px solid transparent;border-right-color:#fafafa}.m-message .self{text-align:right}.m-message .self .avatar{float:right;margin:0 0 0 10px}.m-message .self .text{background-color:#b2e281}.m-message .self .text:before{right:inherit;left:100%;border-right-color:transparent;border-left-color:#b2e281}', ""])
501 }
502 
503 , function(e, t, s) {
504         console.log("[2-3-23]");
505     var r = s(17);
506     "string" == typeof r && (r = [
507         [e.id, r, ""]
508     ]);
509     s(2)(r, {});
510     r.locals && (e.exports = r.locals)
511 }
512 
513 , function(e, t, s) {
514         console.log("[2-3-24]");
515     var r = s(18);
516     "string" == typeof r && (r = [

              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 作者去年就開始使用webpack, 最早的接觸就來自於vue-cli。那個時候工作重點主要也是 vue 的使用,對webpack的配置是知之甚少,期間有問題也是詢問大牛 @呂大豹。順便說一句,對於前端知識體系迷茫的童鞋可以關註豹哥的微信公眾號,《大豹雜說》。豹哥對於剛開始小白的自己(雖然現在也 ...
  • var uploader = new plupload.Uploader({ runtimes: 'html5,flash,silverlight,html4',//用來指定上傳方式,指定多個上傳方式請使用逗號隔開。 browse_button: 'browse',//觸發文件選擇對話框的按鈕,為那 ...
  • 我們從es5的變數提升開始說起, 由於變數提升的原因, 上述程式, 在第2行和第7行都能訪問到a的值, 只不過是undefined, 如果你不熟悉javascript這種變數的預解釋機制,可能會認為第2行和第7行會報錯, 只有flag為true的時候,變數a才聲明瞭, 其實javascript在詞法 ...
  • 用data屬性實例化swiper,在使用中不斷優化 HTML JavaScript ...
  • css如何實現這樣的樣式: 解決方案: 這裡需要用到的技術是border-image的靈活運用,首先需要一張圖片,這裡我選中的是這樣子的,此後 的圖片可以拿這個更改圓形的顏色以更改鋸齒顏色: 底部透明,正方形,ps截圖如下: 好了,下麵咱們就開始真正的代碼: html: <section class ...
  • svg就相當於字體,如何將生成的svg導入到自己的項目中去呢? 1、將類似下麵的文件放入自己的項目中: 2、生成的svg中有一個style.css文件,將裡面的內容拷貝到你的css中,然後更改上圖的路徑即可: 在你的css文件將上圖中的style.css文件拷貝進去即可,如下圖: 註意路徑哦~ 1、 ...
  • meta基礎知識 meta基礎知識 H5頁面視窗自動調整到設備寬度,並禁止用戶縮放頁面 <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,us ...
  • 一、vertical-align 一)定義:定義行內元素的基線相對於該所在基線的垂直對齊。(只針對行類塊inline/inline-block/<img>,塊級不適用!) 二)語法: 三)某些數值: 四)何為基線呢??關於基線 有這樣的說法: 像不像我們小時候寫的英文字母的線,實在是太TMD像了,對 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...