首頁技術(shù)文章正文

Web前端開發(fā)培訓(xùn)之前后端交互指南

更新時(shí)間:2017-06-21 來源:黑馬程序員web前端開發(fā)培訓(xùn)學(xué)院 瀏覽量:

作為剛接觸前端的不久的童鞋,大家都會(huì)興奮于CSS和JS所帶來漂亮界面,然而,前端工程師除了UI重構(gòu)外,還有非常重要的職責(zé)在正確的區(qū)域渲染出服務(wù)端的數(shù)據(jù)。畢竟,我們要構(gòu)建一個(gè)大的web應(yīng)用,必然不是普普通通的靜態(tài)頁面構(gòu)成。

下文將羅列將來前端工程師應(yīng)該必備的同后端打交道的常用技能。

服務(wù)端渲染:

談起服務(wù)端渲染,對于動(dòng)態(tài)服務(wù)而言,這個(gè)世界上跑的大多數(shù)頁面都經(jīng)歷過服務(wù)端的數(shù)據(jù)渲染,接口->前端賦值->模版渲染 。這一切都在服務(wù)器完成,我們查看源碼時(shí)候,可以看到完整的html代碼,包括每個(gè)數(shù)據(jù)值。

常用的php模版有,Smarty,Blade,Mustache,如果你們團(tuán)隊(duì)使用Smarty,我們可以看到一些view的文件里會(huì)前套Smarty的模版語言;

  

[HTML] 純文本查看 復(fù)制代碼
1
<font style="color:rgb(51, 51, 51)"><div> {foreach $list as $item} <h3>{$item['name']}</h3> <p>{$item['desc']}</p> {/foreach} </div></font>

如果Node,js作為服務(wù)端的話,這個(gè)時(shí)候我們可以使用前端模版渲染的模塊,比如ejs,doT,jade等等。

注意不同的模版可能存在不同模版語法,需要自己學(xué)習(xí)使用.

AJAX:

當(dāng)然服務(wù)端渲染隨著單頁應(yīng)用以及Restful接口的興起,Ajax逐漸成為目前前后端交流最為頻繁的方式。Ajax實(shí)際核心是,我們通過對該對象的操作來進(jìn)行異步的數(shù)據(jù)請求。

  

[HTML] 純文本查看 復(fù)制代碼
1
<font style="color:rgb(51, 51, 51)">// 一般流程[/color][/p]  varoReq = new(); oReq.addEventListener( "load", function(res){ // your code to do something}); oReq.open( "GET", "http://www.example.org/example.txt"); oReq.send();</font>

實(shí)際上我們接觸到最多jQuey就有很好的封裝,比如$.ajax,$.post等,如果用Angular的話我們可以用$http服務(wù),除了這些之外,我們可以使用第三方的Ajax庫qwest等。

如果使用Ajax的話,我們不得不面臨一些問題,由于同源限制的問題,我們不得不去克服這個(gè)問題,這個(gè)時(shí)候我們可以要求服務(wù)端,設(shè)置header頭,header('Access-Control-Allow-Origin: *');或者叫設(shè)置nginx配置.

  

[HTML] 純文本查看 復(fù)制代碼
1
<font style="color:rgb(51, 51, 51)"><font style="color:rgb(51, 51, 51)">add_header 'Access-Control-Allow-Origin''http://yourweb.com'; add_header 'Access-Control-Allow-Credentials''true'; add_header 'Access-Control-Allow-Methods''GET';</font></font>

當(dāng)然這不是最好的做法,實(shí)際現(xiàn)在我們也可以這么做:

ajax -> 代理 -> API

我們可以用php的curl或者通過服務(wù)器的配置來實(shí)現(xiàn)反向代理。從而達(dá)到同源的效果。

前端工程師一定要要求每次請求的數(shù)據(jù)接口一嚴(yán)格遵循基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)要求,盡管js是弱變量類型語言,但是我們還是應(yīng)該嚴(yán)格要求,是數(shù)組,就不應(yīng)該是對象,是數(shù)字就不應(yīng)該是字符串,這樣做有利于降低隱藏bug并且提升前后端工作效率。

JSONP:

JSONP算作JSON的一種"使用模式",可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。由于CORS的支持,我們可以簡單的將數(shù)據(jù)封裝成一個(gè)js腳本請求,當(dāng)然我們在jquery中會(huì)用到。

  

[HTML] 純文本查看 復(fù)制代碼
1
<font style="color:rgb(51, 51, 51)"><font style="color:rgb(51, 51, 51)">functionlogResults(json){ console.log(json); } $.ajax({ url: "https://yourapi.com/api", dataType:"jsonp", jsonpCallback: "logResults"}); Comet</font></font>

Comet:

聊Comet我們還得說下短輪詢,由于某些特定的業(yè)務(wù)需求,比如通知,我們需要有及時(shí)的數(shù)據(jù)更新,我們能夠想到的就是使用setInterval每隔一定時(shí)間比如10s去獲取一次請求,從而做到一些通知更新,但是這并不一種高效的做法,這會(huì)增加服務(wù)器的請求數(shù)量。這個(gè)時(shí)候有了另外一種概念,“反向Ajax”,由服務(wù)器進(jìn)行數(shù)據(jù)推送, Comet能夠讓信息近乎實(shí)時(shí)的被推送到頁面上,非常適合要求實(shí)時(shí)性的獲取的數(shù)據(jù)的頁面。

   

如圖所示,就是一個(gè)簡單的Comet模型,就是數(shù)據(jù)請求后掛起,直到有數(shù)據(jù)響應(yīng)推送到客戶端,這個(gè)時(shí)候客戶端再發(fā)起一個(gè)新的連接。

  

這樣相對來說可以減少一定數(shù)量的請求,以及數(shù)據(jù)的及時(shí)響應(yīng),從而一定意義的實(shí)現(xiàn)所謂推送。

  

一個(gè)簡單的PHP Demo代碼,就是我們需要這端代碼一直運(yùn)行著...

  while( true) { set_time_limit( 0); echo 'data'; flush(); b_flush(); sleep( 3); }

JavaScript:

  

[JavaScript] 純文本查看 復(fù)制代碼
1
<font style="color:rgb(51, 51, 51)">[mw_shl_code=html,true]functioncreateStreamingClient(url,progress,finished){ varxhr= new(),received= 0; xhr.open("get",url, true); xhr.onreadystatechange= function(){ varresult; if(xhr.readyState== 3){ result=xhr.responseText.substring(received); received+=result.length; progress(result); }elseif(xhr.readyState== 4){ finished(xhr.responseText); } }; xhr.send( null); returnxhr; } // var client = createStreamingClient(url,fuc1,func2)</font>

SSE Server-Sent Events:

SSE是圍繞只讀Comet交互推出的API或者模式。SSE API用于創(chuàng)建到服務(wù)器的單向連接,服務(wù)器通過這個(gè)連接可以發(fā)送任意數(shù)量的數(shù)據(jù)。服務(wù)器響應(yīng)的MIME類型必須是text/event-stream,而且是瀏覽器中的Java API能解析的格式輸出。

   

現(xiàn)對于Comet,我們可以看出我們只進(jìn)行了一次連接,然后服務(wù)端會(huì)去控制數(shù)據(jù)的響應(yīng),從而發(fā)送給客戶端。這樣相對來說,但是如同定義的描述,這種只適合只讀數(shù)據(jù)的情形。比如一些通知和狀態(tài)碼這樣的。SEE的使用非常簡單,只需要掌握這幾個(gè)api就行:

  

[JavaScript] 純文本查看 復(fù)制代碼
1
2
3
4
<font style="color:rgb(51, 51, 51)">vares = newEventSource( 'http://your.api.com'[/color][/p]  functionlistener(event){ console.log(event.data); } // 創(chuàng)建一個(gè)SSE連接
  es.addEventListener( "open", listener); // 響應(yīng)獲取消息的事件
  es.addEventListener( "message", listener); // 發(fā)生錯(cuò)誤
  es.addEventListener( "error", listener);</font>

注意:如果在回話過程中遇見錯(cuò)誤后,默認(rèn)程序會(huì)重新發(fā)起一次新的連接,從而防止掛掉就不再響應(yīng)了

服務(wù)端(node,php)的代碼,可以參考:https://github.com/Yaffle/EventSource

Web Sockets:

HTML5 WebSocket 設(shè)計(jì)出來的目的就是要取代輪詢和 Comet 技術(shù),使客戶端瀏覽器具備像 C/S 架構(gòu)下桌面系統(tǒng)的實(shí)時(shí)通訊能力。 瀏覽器通過 Java 向服務(wù)器發(fā)出建立 WebSocket 連接的請求,連接建立以后,客戶端和服務(wù)器端就可以通過 TCP 連接直接交換數(shù)據(jù)。也就是我們可以使用web技術(shù)構(gòu)建實(shí)時(shí)性的程序比如聊天游戲等應(yīng)用。

其實(shí)Web Sockets 的API很少,就下面這些:

 

[JavaScript] 純文本查看 復(fù)制代碼
1
2
3
4
5
6
<font style="color:rgb(51, 51, 51)"> websocket = newWebSocket( "ws://your.socket.com:9001"); // 大開[/color][/p]  websocket.onopen = function(evt){ /* do stuff */}; //on open event // 當(dāng)web socket關(guān)閉
  websocket.onclose = function(evt){ /* do stuff */}; // 進(jìn)行通信時(shí)
  websocket.onmessage = function(evt){ /* do stuff */}; // 發(fā)生錯(cuò)誤時(shí)
  websocket. = function(evt){ /* do stuff */}; // 向服務(wù)器發(fā)發(fā)送消息
  websocket.send(message); //send method
  websocket.close(); //close method</font>

對于服務(wù)端的話,PHP支持了很多socket 相關(guān)api,但是我們可以使用更加成熟的框架(實(shí)用)比如phpsocket.io,Ratchet.當(dāng)然node.js寫 socket也非常得心應(yīng)手,node.js對高并發(fā)支持相對較好,可以使用http://socket.io/。

服務(wù)端大概會(huì)做下面的事情: + 創(chuàng)建一個(gè)socket + 綁定地址和端口 + 監(jiān)聽進(jìn)入的連接 + 接收新的連接 + web socket 握手 + 解碼數(shù)據(jù)


小結(jié):

說了那么多簡單總結(jié)下,大家想明白幾點(diǎn)就行了,客戶端與服務(wù)端誰先主動(dòng),是否強(qiáng)調(diào)數(shù)據(jù)的實(shí)時(shí)性。

  • AJAX - 請求 → 響應(yīng) (頻繁使用)
  • Comet - 請求 → 掛起 → 響應(yīng) (模擬服務(wù)端推送)
  • Server-Sent Events - 客戶單 ← 服務(wù)端 (服務(wù)端推送)
  • WebSockets - 客戶端 ? 服務(wù)端 (未來趨勢,雙工通信)


    本文版權(quán)歸河馬程序員web前端開發(fā)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處,謝謝!
    作者:河馬程序員web前端培訓(xùn)學(xué)院;
    首發(fā):http://web.itheima.com/ 
分享到:
在線咨詢 我要報(bào)名
和我們在線交談!