javascript 簡單的3d網頁應用(3d網頁可視化編輯器), 搭建幾何體 選配材質 紋理 , 導入 導出 示例 ( three.js 初探 六)

来源:https://www.cnblogs.com/weihexinCode/archive/2020/04/01/12609829.html
-Advertisement-
Play Games

1 完整代碼下載 https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ 提取碼 3fzt (壓縮包名: 2020-3-24-demo.zip) 2 圖片展示 3 主要代碼 布爾運算後的物體的幾何體會自動 導入到 幾何體列表選項中, 可自由選配材質 紋理 挺簡 ...


1 完整代碼下載

  https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ  

  提取碼 3fzt (壓縮包名: 2020-3-24-demo.zip)

2 圖片展示

 

 

3 主要代碼

  布爾運算後的物體的幾何體會自動 導入到 幾何體列表選項中, 可自由選配材質 紋理

  挺簡單, 都是中文

 

  1 "use strict"
  2 
  3 var View = (function (){
  4     
  5     var _View = function (){
  6         
  7         if(this.__proto__.size === undefined){this.__proto__.size = this.getSize();}
  8         
  9     }
 10     
 11     _View.prototype = {
 12         
 13         constructor: _View, 
 14         
 15         //創建html元素
 16         add: function (fel, elemName, id, cls){
 17             let el = document.createElement(elemName);
 18             if(id){el.setAttribute('id',id);}
 19             if(cls){el.className = cls;}
 20             if(fel){fel.appendChild(el);}
 21             return el;
 22         }, 
 23         
 24         //刪除html元素
 25         remove: function (){
 26             let k, arg = arguments, err = [];
 27             for(k = 0; k < arg.length; k++){
 28                 if(this.isEl(arg[k]) === false){err.push(arg[k]); continue;}
 29                 arg[k].parentNode.removeChild(arg[k]);
 30             }
 31             if(err.length > 0){return {err:'這裡有一些刪除失敗的元素', arr:err};}
 32             return true;
 33         }, 
 34 
 35         //id獲取html元素
 36         get: function (id){
 37             return document.getElementById(id);
 38         }, 
 39         
 40         //獲取可視寬高
 41         getSize: function (){
 42             let w = window.innerWidth ||  document.body.clientWidth || document.documentElement.clientWidth;
 43             let h = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight;
 44             return {w:w, h:h};
 45         }, 
 46          
 47         //通過parentNode檢查元素是否存在於頁面中
 48         isEl: function (el){
 49             if(typeof(el) !== 'object'){return false;}
 50             //被刪除之後的html元素object的 parentNode等於null
 51             if(!el.parentNode){return false;}
 52             return true;
 53          }, 
 54          
 55         //元素綁定事件
 56         addEvent: function (target, ev, callback){
 57             target.addEventListener(ev, function(e){/* e.preventDefault(); */ if(callback){callback(e);}}, false);
 58             return callback;
 59         }, 
 60         
 61         removeEvent: function (target, ev, func){
 62             target.removeEventListener(ev, func);
 63         }, 
 64         
 65         initBody: function (){
 66             document.body.style.width = this.size.w + "px";
 67             document.body.style.height = this.size.h + "px";
 68             document.body.style.overflow = "hidden";
 69             return this;
 70         }
 71         
 72     }
 73     
 74     return _View;
 75     
 76 })()
 77 
 78 
 79 
 80 /**
 81     限 谷歌 或 火狐 瀏覽器
 82     依賴 View 類
 83 */
 84 var Gui = (function (){
 85     
 86     //申明新的gui
 87     var _Gui = function (obj, a, b, c, d){
 88         this.timer = 0;
 89         this.info = new Map();
 90         //this.info.set(this.timer, this);
 91         if(this.__proto__.timerAll_old.length !== 0){
 92             this.timerAll = this.__proto__.timerAll_old[0];
 93             this.__proto__.timerAll_old.splice(0, 1);
 94         }else{
 95             this.__proto__.timerAll++;
 96             this.timerAll = this.__proto__.timerAll;
 97         }
 98         this.elem = addBindMove(document.body, 'div', null, 'Gui box-shadown box-scroll-block');
 99         this.__proto__.objAll.set(this.timerAll, this);
100         let dis = this.autoChangeStartPosition === false ? 1 : this.timerAll;
101         this.setPos(15 * dis, 5 * dis, "right");
102         if(typeof(obj) === "object" && Array.isArray(obj) === false){this.create(obj, a, b, c, d);}
103         else{/* console.warn("_Gui: 參數中的對象 格式錯誤"); */}
104     }
105 
106     _Gui.prototype.objAll = new Map();
107     
108     _Gui.prototype.timerAll = 0;
109     
110     _Gui.prototype.timerAll_old = [];
111     
112     _Gui.prototype.autoChangeStartPosition = true; //自動改變初始位置
113     
114     //創建新的塊
115     _Gui.prototype.create = function (obj, a, b, c, d){
116         this.timer++;
117         _start(obj, a, b, c, d, this.timer, this.elem, this.info, this.timerAll, this.objAll);
118         return this;
119     }
120     
121     //往塊里添加新的控制項
122     _Gui.prototype.add = function (obj, a, b, c, d){
123         _start(obj, a, b, c, d, this.timer, this.elem, this.info, this.timerAll, this.objAll);
124         return this;
125     }
126     
127     //添加 內容變動 回調(change 事件)
128     _Gui.prototype.change = function (){//arr.concat(arr_a, arr_b)
129         var arg = arguments, o = this.info.get(this.timer), tar = o.par.target;
130         var arr = tar.bs.concat(tar.fs, tar.ns, tar.ss, tar.ts, tar.cs), len = arr.length;
131         var arg_t_0 = typeof(arg[0]), call = o.objs.get(o.obj).callback;
132         if(arg_t_0 === "function" && len === 1){
133             call[arr[0]] = arg[0];
134         }else if(arg_t_0 === "string" && typeof(arg[1]) === "function"){
135             call[arg[0]] = arg[1];
136         }else if(arg_t_0 === "function" && len > 1){
137             for(let k = 0; k < len; k++){
138                 call[arr[k]] = arg[0];
139             }
140         }else if(arg_t_0 === "object" && Array.isArray(arg[0]) === false){
141             for(let k in arg[0]){
142                 call[k] = arg[0][k];
143             }
144         }else{
145             console.log("change方法參數錯誤,添加失敗");
146         }
147         //console.log(this.info.get(this.timer).obj);
148         return this;
149     }
150     
151     //修改title
152     _Gui.prototype.title = function (value){
153         if(!this.info.get(this.timer)){console.log("找不到title"); return;}
154         this.info.get(this.timer).title.innerHTML = "<span class='timerAll'>"+this.timerAll+"</span>"+"."+"<span class='timer'>"+this.timer+"</span>"+" "+(value || "");
155         return this;
156     }
157     
158     //修改name
159     _Gui.prototype.name = function (){
160         let o = this.info.get(this.timer), objs;
161         let arg = arguments, typ0 = typeof(arg[0]), typ1 = typeof(arg[1]);
162         if(typeof(arg[2]) === "object" && Array.isArray(arg[2]) === false){objs = o.objs.get(arg[2]);}else{objs = o.objs.get(o.obj);}
163         var tar = objs.parameter.target, nameEl = objs.nameEl;
164         var arr = tar.bs.concat(tar.fs, tar.ns, tar.ss, tar.ts, tar.cs), len = arr.length;
165         
166         var setVal = (el, val)=>{if(el.value !== undefined){el.value = val;}else if(el.innerHTML !== undefined){el.innerHTML = val;}else{console.log("name修改失敗");}}
167 
168         if(typ0 === "string" && typ1 === "undefined" && len === 1){//string
169             setVal(nameEl[arr[0]], arg[0]);
170 
171         }else if(typ0 === "object" && Array.isArray(typ0) === false){//object
172             let k;
173             for(k in arg[0]){
174                 setVal(nameEl[k], arg[0][k]);
175             }
176                 
177         }else if(typ0 === "string" && typ1 === "string" && arg[1] !== "_Gui_func_showStop"){//string, string
178             if(arr.indexOf(arg[0]) === -1 || !nameEl[arg[0]]){console.log("name修改失敗,視圖結構發生錯誤,請修複"); return;}
179             setVal(nameEl[arg[0]], arg[1]);
180             
181         }else if(typ0 === "string" && arg[1] === "_Gui_func_showStop" && typeof(arg[2]) === "object"){
182             if(nameEl[arg[0]] === undefined){console.log("showStop_name: 錯誤"); return;}
183             if(arg[3] === false){
184                 nameEl[arg[0]].style.color = "#2F4F4F";
185             }else{
186                 nameEl[arg[0]].style.color = "red";
187             }
188             
189             
190         }else{
191             console.log("name方法參數錯誤,添加失敗");
192         }
193             
194         return this;
195     }
196     
197     //獲取當前view對象
198     _Gui.prototype.getView = function (){
199         return tar;
200     }
201     
202     //設置 gui視圖位置
203     _Gui.prototype.setPos = function (x, y, dirX, dirY){
204         
205         let dirx = dirX || "left", diry = dirY || "top";
206 
207         if(dirx === "left" && this.elem.bindMove.style.right !== ""){
208             this.elem.bindMove.style.right = "";
209         }
210         else if(dirx === "right" && this.elem.bindMove.style.left !== ""){
211             this.elem.bindMove.style.left = "";
212         }
213         
214         if(diry === "top" && this.elem.bindMove.style.bottom !== ""){
215             this.elem.bindMove.style.bottom = "";
216         }
217         else if(diry === "bottom" && this.elem.bindMove.style.top !== ""){
218             this.elem.bindMove.style.top = "";
219         }
220         
221         if(x !== undefined) this.elem.bindMove.style[dirx] = x+"px";
222         if(y !== undefined) this.elem.bindMove.style[diry] = y+"px";
223         _setElemPos(this.elem);
224         
225         return this;
226         
227     }
228     
229     //隱藏gui
230     _Gui.prototype.display = function (val){
231         if(!this.elem){console.log("display, elem不存在"); return this;}
232         if(val !== "block" && val !== "none"){console.log("display 參數錯誤"); return this;}
233         this.elem.bindMove.style.display = val;
234         this.elem.style.display = val;
235         return this;
236     }
237     
238     //關閉gui timer number, 可選, 關閉那個 timer塊(預設關閉整個Gui)
239     _Gui.prototype.close = function (timer){
240         if(timer === "auto"){
241             
242             return this;
243         }
244         var o = this.info.get(timer);
245         if(o === undefined){
246             let k;
247             for(k = 1; k <= this.timer; k++){
248                 o = this.info.get(k);
249                 o.hide = true;
250                 hide(o.line, o.fel, this.elem, this.info, true);
251             }
252         }else{
253             o.hide = true;
254             hide(o.line, o.fel, this.elem, this.info, true);
255         }
256         return this;
257     }
258     
259     //標記不可用項
260     _Gui.prototype.showStop = function (){
261         
262         this.name(arguments[0], "_Gui_func_showStop", arguments[1], arguments[2]);
263         
264         return this;
265         
266     }
267     
268     //移除gui
269     _Gui.prototype.remove = function(object){
270         var o = object ? object : this;
271         this.__proto__.timerAll_old.push(o.timerAll);
272         this.__proto__.objAll.delete(o.timerAll);
273         o.objAll.delete(o.timerAll);
274         tar.remove(o.elem.bindMove, o.elem);
275         delete(o.timerAll);
276         delete(o.elem);
277         delete(o.info);
278         delete(o.timer);
279         return;
280     }
281     
282     
283     
284     
285     var tar = new View(), tar_zIndex = {}, _osTitle = null;
286 
287     //創建視圖
288     var _start = function (obj, a, b, c, d, id, felem, map, timerAll, objAll){
289             
290             var fel, line, title, m = map.get(id), k, len, _name, isNewObj = false;
291             
292             //確認追加 obj
293             if(m){
294                 fel = m.fel;
295                 if(!obj){
296                     obj = m.obj;
297                 }else{
298                     if(m.objs.has(obj) === false) isNewObj = true;
299                     m.obj = obj;
300                 }
301             }
302 
303             if(typeof(obj) !== "object" || !obj){console.log("引用對象錯誤, 新建塊對象為必須"); return;}
304             
305             //確認參數 (target, title, isBind, range || select) || a = {target, title, isBind, range || select}
306             var os = {}, nos = [];
307             if(a !== undefined){nos.push(_getispro(obj, a, nos));}
308             if(b !== undefined){nos.push(_getispro(obj, b, nos));}
309             if(c !== undefined){nos.push(_getispro(obj, c, nos));}
310             if(d !== undefined){nos.push(_getispro(obj, d, nos));}
311             len = nos.length;
312             for(k = 0; k < len; k++){
313                 if(nos[k] === undefined){
314                     if(typeof(a) === "object" && Array.isArray(a) === false){os = a;}
315                 }else{
316                     let val;
317                     switch(k){
318                         case 0 : val = a; break;
319                         case 1 : val = b; break;
320                         case 2 : val = c; break;
321                         case 3 : val = d; break;
322                         default : break;
323                     }
324                     if(val !== undefined){os[nos[k]] = val;}
325                 }
326             }
327             
328             //確認對象屬性 os.target (target 如果為obj 則表示 只設置gui, 不添加控制項)
329             var arr = [], T = typeof(os.target), A = Array.isArray(os.target);
330             if(!os.target){for(k in obj){arr.push(k);}}
331             else if(A === true){arr = os.target;}
332             else if(T !== "object"){arr.push(os.target);}
333             else{return;} 
334             //boolean, function, number, text, select, color
335             var bs = [], fs = [], ns = [], ts = [], cs = [], ss = [];
336             if(Array.isArray(os.select) == true && arr.length === 1){
337                 ss.push(arr[0]);
338             }else if(typeof(os.select) === "object" && Array.isArray(os.select) == false){
339                 let ks;
340                 for(ks in os.select){
341                     len = arr.length;
342                     for(k = 0; k < len; k++){
343                         if(ks === arr[k]){ss.push(arr[k]); arr.splice(k, 1);}
344                     }
345                 }
346             }
347             len = arr.length;
348             for(k = 0; k < len; k++){
349                 T = typeof(obj[arr[k]]);
350                 if(T === "boolean"){bs.push(arr[k]);}
351                 else if(T === "function"){fs.push(arr[k]);}
352                 else if(T === "number"){ns.push(arr[k]);}
353                 else if(T === "string"){
354                     if(obj[arr[k]].length === 7 && obj[arr[k]].charAt(0) === "#"){cs.push(arr[k]);}//color
355                     else{ts.push(arr[k]);}//string
356                 }
357             }
358             var bs_len = bs.length, fs_len = fs.length, ns_len = ns.length, ts_len = ts.length, ss_len = ss.length, cs_len = cs.length;
359             var lens = bs_len + fs_len + ns_len + ts_len + ss_len + cs_len;
360             
361             //確認 綁定
362             var isB = false;
363             if(typeof(os.isBind) === "boolean"){isB = os.isBind;}
364             
365             //確認 _name
366             if(os.title && lens === 1){_name = os.title; delete(os.title);}
367             
368             //確認 新的塊
369             var par = {target:{bs:bs, fs:fs, ns:ns, ts:ts, cs:cs, ss:ss}, select:os.select, range:os.range, title:os.title, isBind:os.isBind};
370             if(!m){
371                 isNewObj = false;
372                 line = _line(id, felem);
373                 fel = _cons(line, id, felem, map);
374                 title = _title(timerAll, id, _osTitle || os.title, fel);//os.title
375                 _osTitle = null;
376                 map.set(id, {
377                     hide : false,
378                     line : line, 
379                     fel : fel, 
380                     title : title, 
381                     obj : obj, 
382                     par : par,
383                     objs : new Map([[obj, {
384                         parameter : par,
385                         callback : {},
386                         nameEl : {}
387                     }]])
388                 });
389                 m = map.get(id);
390             }
391             
392             //更新 obj
393             if(isNewObj === true){
394                 m.objs.set(obj, {
395                     parameter : par,
396                     callback : {},
397                     nameEl : {}
398                 });
399             }
400             
401             //更新參數
402             m.par = par;
403             var objs_g = m.objs.get(obj), pars = objs_g.parameter;
404             for(k in os){if(k !== "target"){pars[k] = os[k];}}
405             for(k = 0; k < bs_len; k++){if(pars.target.bs.indexOf(bs[k]) === -1){pars.target.bs.push(bs[k]);}}
406             for(k = 0; k < fs_len; k++){if(pars.target.fs.indexOf(fs[k]) === -1){pars.target.fs.push(fs[k]);}}
407             for(k = 0; k < ns_len; k++){if(pars.target.ns.indexOf(ns[k]) === -1){pars.target.ns.push(ns[k]);}}
408             for(k = 0; k < ts_len; k++){if(pars.target.ts.indexOf(ts[k]) === -1){pars.target.ts.push(ts[k]);}}
409             for(k = 0; k < ss_len; k++){if(pars.target.ss.indexOf(ss[k]) === -1){pars.target.ss.push(ss[k]);}}
410             for(k = 0; k < cs_len; k++){if(pars.target.cs.indexOf(cs[k]) === -1){pars.target.cs.push(cs[k]);}}
411 
412             //console.log(objs_g.callback);
413             //創建視圖//os.select os.range os.isBind
414             let che, cli, ran, tex, col, sel;
415             if(bs_len > 0){ che = _check(obj, bs, fel, isB, objs_g.callback, _name); for(k in che.nameEl){objs_g.nameEl[k] = che.nameEl[k];} }
416             if(ts_len > 0){ tex = _text(obj, ts, fel, isB, objs_g.callback, _name); for(k in tex.nameEl){objs_g.nameEl[k] = tex.nameEl[k];} }
417             if(cs_len > 0){ col = _color(obj, cs, fel, isB, objs_g.callback, _name); for(k in col.nameEl){objs_g.nameEl[k] = col.nameEl[k];} }
418             if(ss_len > 0){ sel = _select(obj, ss, os.select, fel, isB, objs_g.callback, _name); for(k in sel.nameEl){objs_g.nameEl[k] = sel.nameEl[k];} }
419             if(ns_len > 0){ ran = _range(obj, ns, os.range || {}, fel, isB, objs_g.callback, timerAll, id, _name); for(k in ran.nameEl){objs_g.nameEl[k] = ran.nameEl[k];} }
420             if(fs_len > 0){ cli = _click(obj, fs, fel, objs_g.callback, _name); for(k in cli.nameEl){objs_g.nameEl[k] = cli.nameEl[k];} }
421             return {nowObject:obj};
422     }
423         
424         //驗證 並 獲取 _start 參數
425         var _getispro = function (obj, cons, nos){
426             var o_t = typeof(cons), o_a = Array.isArray(cons), r;
427             if(o_t === "string"){
428                 if(obj[cons] !== undefined){
429                     r = "target";
430                 }
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 你也許會覺得Web前端開發是一個很簡單的工作,但當你深入其中時,一定會發現好像Web前端開發不是那麼簡單,光網站性能優化、響應式、框架就讓你焦頭爛額。確實,做前端開發就是先易後難,想成為一個優秀的Web前端開發,沒有那麼簡單。不過,天下事難則不會,會則不難,你只需要掌握11項技能就可以成為Web前端 ...
  • 向組件中插入內容有2種方式 槽點 子組件 demo 使用槽點向組件中插入內容 Vue.component('Parent',{ template:` <!--反引號比引號更好用--> <div> <p>hello</p> <slot></slot> <!--如果後續要在組件中插入元素、內容,需要先留 ...
  • 如圖,想實現模糊查詢點擊文字賦值到搜索框,離開則關閉模糊查詢提示,但失去焦點時模糊查詢div隱藏就無法實現點擊賦值的事件了,這時候需要隱藏時判斷是否離開模糊查詢,附上代碼 //全局變數 var x,y; $(document).mousemove(function(e){ x = e.pageX; ...
  • [toc] 術語 1. web:互聯網。 2. w3c:萬維網聯盟,非盈利組織,官網:w3.org。為互聯網提供各種標準。 1. 代替網址:MDN:Mozilla Development Network。Mozilla開發者社區。有中文。 3. ISO:國際標準組織。 4. XML: 可擴展 的標記 ...
  • 很多讀者經常問我:愷哥,我怎麼樣才能進階前端呀?能推薦一些資料嘛? 首先我們定個基調,這裡的進階指的是讓自己成為厲害點的人,能夠找工作不難的人,相信大家都是想成為這樣的選手吧~ 其實大部分情況下你多學會了一門框架 / 庫的使用,或者多會了一門語言,確實能讓你做的事情更多了,但是離你真正實現技術進階還 ...
  • 將頁面拆分為多個組件,簡化了頁面開發,方便維護,組件也可以復用。 組件的類型 通用組件,比如表單、彈窗、菜單欄、分頁組件等 業務組件,實現某一業務的組件,比如抽獎組件 頁面組件,也叫做單頁,一個頁面就是一個組件,只完成功能,不復用 組件開發流程:聲明、註冊、使用 demo 組件使用流程 <div i ...
  • 按照國際慣例先放效果圖 項目結構搭建 首先修改app.vue <template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> * ...
  • 前面業務里有個搜索功能 , 入口比較深 , 現在想要把入口挪到有公共header的地方 , 在不想完全實現一遍功能的情況下 , 就需要模擬進行多個點擊事件來執行點擊後的效果 執行先點擊1 ,再給inout賦值 ,再點擊2 基本思路是類似jquery的trigger方法 , 原生js也是可以實現 , ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...