WEB開發:如何用js來模擬服務器的ajax響應,不依賴服務器來編寫前端代碼


一、問題的提出

目前web前端開發,主流的思路是:

1)編寫靜態的html文件(不使用模板技術,與服務器無關)

2)頁面通過ajax與服務器交互,進行數據的傳輸,數據格式為json格式

這里存在一個問題,因為有大量的與服務器的ajax交互,前端代碼的編寫與測試對服務器的依賴很大。這有時可能會影響前端的開發效率。

本文我們提出一種方法,就是通過用js模擬服務器的請求響應,使的前端代碼可以獨立開發和調試,當最后實際與服務器交互時,只需替換下api即可,工作量很小。

 

二、解決方案

具體的做法是:

1、定義一個js類,如:

function MockServer(){

}

2、定義一個方法,如:

MockServer.prototype.ajax = function(url,paras,handle){

}

正常情況下,頁面中需要向服務器發送ajax請求,需要調用相應的ajax api (具體的api依賴所使用的框架,一般開發web前端都會使用某個或多個框架,如最常用的jquery框架)。但不管是使用哪個框架的ajax api,其核心的信息包括三個部分:

1)請求的url。 服務器針對不同的url會給出不同的處理。

2)js傳給服務器的參數,通常是一個json對象

3)服務器處理返回消息的回調函數

我們這里提供的ajax方法的參數正好是這三部分內容。

這時編寫js代碼時,就先調用這個ajax方法發送請求。到時再替換具體框架的api,這個工作量相對很小的,只需替換下api即可,其它代碼基本不用變。

上面定義的ajax中組裝需要返回到瀏覽器的數據(是個json對象),然后調用調用者提供的handle回調函數,參數就是要返回的json對象。

因為ajax的請求時異步響應的,為了使流程更加真實,我們在這個ajax方法中使用setTimeout方法來實現異步的響應。該方法的實現代碼如下:

MockServer.prototype.ajax = function(url,paras,handle){
   var result={};
   .............
   //給result對象設置值,該result對象就是返回到ajax請求的數據
   window.setTimeout(handle,parseInt(10*Math.random())+10,result);
}

可以看出,上面代碼利用 Math.random 方法獲取一個隨機數(以便更加真實),然后設置定時器,當隨機數時間到了,

就調用回調函數,參數是result對象。 在這之前,需要根據不同的url,給result設置不同的返回值,這個按照業務邏輯來處理就行了。

調用者的代碼如:

  var mockServer = new MockServer(); 
   mockServer.ajax("loadmyokr",{},function(result){
        if(result.errorcode){
            alert("操作失敗,錯誤原因是:"+result.errorinfo);
            return;
        }
        showData(result.data);
    });

當和服務器真實交互時,將上面的api換成實際使用的api即可。甚至還可以進一步處理,這個api就保留,到時在這個api中再次封裝即可。
這樣js代碼就幾乎可以實現不用修改。

 

三、進一步深入

在實際的服務器代碼中,數據是會持久化的,也就是說客戶端與服務器交互引起的數據變化會持久化。

當頁面重新刷新后,會獲取到最新的變化后的數據。

如果我們只是在上面的ajax方法代碼中根據業務需求封裝返回客戶端的json對象,這些都是在內存中操作的,因為MockServer類本身就是js類,存在於客戶端。

一旦頁面刷新,所有頁面操作引起的數據變化都沒了,每次刷新頁面都會回到初始界面。

初始界面本身這個倒沒有大問題。最大的問題是這樣會導致客戶端js的代碼很可能考慮不全,存在邏輯錯誤或遺漏的地方。

為了更加真實的模擬服務器。

我們可以利用html5的 Web Storage APi 讓這些模擬的數據持久化到客戶端機器上。這樣在交互過程中發生的數據變化都會被持久化下來。

一旦頁面刷新后,也可以取到持久化的數據。這樣就更加真實的模擬了服務器的行為。使得客戶端的代碼基本上就是真實的。

下面我們給出MockServer類的示例代碼:

function MockServer(){
    if(!window.localStorage["mydata"]){
        window.localStorage["mydata"]="{}";
    }
    this.mydata = window.localStorage["mydata"];
}    

MockServer.prototype.ajax = function(url,paras,handle){
    //下面這語句很重要,因為localStorage中存放的是鍵值對,
    //目前大多瀏覽器支持的值都是字符串,需要調用JSON的api轉換成json對象,以便於后續的處理
    this.mydata = JSON.parse(this.mydata); 
    
    //下面代碼就是根據不同的url請求,對this.mydata對象中的內容進行讀取和更新
    //並設置返回給客戶端的result對象
    // this.mydata 變量不是必須的,這么做只是為了放便。
    //這樣對各url請求的處理就聚焦到對this.mydata對象的處理,不用關心存儲等公共的事情了。
    ..... 
    
    //下面這語句也很重要,因為前面處理的this.mydata已經是json對象,
    //需要把它轉換成字符串后才能存儲到localStorage中
    window.localStorage["mydata"] = JSON.stringify(this.mydata);
    
    //重新將保存到localStorage中的字符串值賦值給this.mydata變量
    this.mydata = window.localStorage["mydata"];
    
    
    //設置定時器,調用回調函數
    window.setTimeout(handle,parseInt(10*Math.random())+10,result);
}

 

四、還能進一步嗎

上滿我們利用html5de WEB storage功能在瀏覽器本地對數據做持久化。

除此之外,我們還可以利用WEB sql database 功能在瀏覽器對數據做持久化。這么做會讓模擬代碼更接近服務器的處理代碼(因為大部分場景下數據都是存在數據庫的)。 如果這時服務器采用nodejs開發。也許很多客戶端的代碼和服務器的nodejs代碼就能共享了。

 

五、小結

采用上的策略,我們很好地解決了web前端開發時對服務器的依賴。在我們的實際項目應用中反饋也是非常不錯的。

這個也沒有太多的技術含量。只是一個開發思路的轉變。

這種思路其實不僅是讓前端的開發更加方便。其實它也有利於客戶端和服務器的接口定義更加合理。

在我們傳統的開發方式中, 我們需要先協商客戶端和服務器的接口(主要內容包括上面介紹的三部分,即url,請求參數,返回值)。

但是畢竟是事先定義的,可能再隨着客戶端的開發中,會發現這個預先定義的接口不太適合,這時又需要協商修改。

無形中會帶來額外的工作量,包括維護的工作量,甚至會因為接口的同步不及時導致客戶端無法正常運行。

而采用這種模擬的方式,客戶端完全可以根據自己的需要設計api,並在開發的過程自由調整,一旦客戶端代碼定型后,只要提交一份需求給服務器即可,這個時候定義的接口一定是比較適合和穩定的。這樣出來的api也是比較易於做自動化測試的。

這種做法尤其是在客戶端和服務器分工開發的團隊中非常適合,雖然我們現在鼓勵全棧程序員,但前段技術和后端技術是有差異的,在實際的項目開發中大家的分工往往還是有側重點的。

采用這種方式,客戶端的開發者不用關心服務器采用的技術,可以聚焦在頁面的設計、頁面代碼的編寫中。

服務器代碼的編寫者一樣可以不關心客戶端,可以更加關注服務器代碼的邏輯、性能、架構等方面。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM