轉自原文 寫給剛入門的前端工程師的先後端交互指南javascript
做爲剛接觸前端的不久的童鞋,你們都會興奮於CSS和JS所帶來漂亮界面,然而,前端工程師除了UI重構外,還有很是重要的職責在正確的區域渲染出服務端的數據。畢竟,咱們要構建一個大的web應用,必然不是普普統統的靜態頁面構成。php
下文將羅列未來前端工程師應該必備的同後端打交道的經常使用技能。html
談起服務端渲染,對於動態服務而言,這個世界上跑的大多數頁面都經歷過服務端的數據渲染,接口->前端賦值->模版渲染 。這一切都在服務器完成,咱們查看源碼時候,能夠看到完整的html代碼,包括每一個數據值。前端
經常使用的php模版有,Smarty
,Blade
,Mustache
,若是大家團隊使用Smarty,咱們能夠看到一些view的文件裏會前套Smarty的模版語言;java
<div>
{foreach $list as $item} <h3>{$item['name']}</h3> <p>{$item['desc']}</p> {/foreach} </div>
若是Node,js做爲服務端的話,這個時候咱們可使用前端模版渲染的模塊,好比ejs
,doT
,jade
等等。node
注意不一樣的模版可能存在不一樣模版語法,須要本身學習使用jquery
固然服務端渲染隨着單頁應用以及Restful接口的興起,Ajax逐漸成爲目前先後端交流最爲頻繁的方式。Ajax實際核心是XmlHttpRequest
,咱們經過對該對象的操做來進行異步的數據請求。nginx
// 通常流程
var oReq = new XMLHttpRequest(); oReq.addEventListener("load", function(res) { // your code to do something }); oReq.open("GET", "http://www.example.org/example.txt"); oReq.send();
實際上咱們接觸到最多jQuey就有很好的封裝,好比$.ajax
,$.post
等,若是用Angular的話咱們能夠用$http
服務,除了這些以外,咱們可使用第三方的Ajax庫qwest等。git
若是使用Ajax的話,咱們不得不面臨一些問題,因爲同源限制的問題,咱們不得不去克服這個問題,這個時候咱們能夠要求服務端,設置header頭,header('Access-Control-Allow-Origin: *');
或者叫設置nginx配置github
add_header 'Access-Control-Allow-Origin' 'http://yourweb.com'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET';
固然這不是最好的作法,實際如今咱們也能夠這麼作:
ajax -> 代理 -> API
咱們能夠用php的curl或者經過服務器的配置來實現反向代理。從而達到同源的效果。
前端工程師必定要要求每次請求的數據接口一嚴格遵循基礎的數據結構要求,儘管js是弱變量類型語言,可是咱們仍是應該嚴格要求,是數組,就不該該是對象,是數字就不該該是字符串,這樣作有利於下降隱藏bug而且提高先後端工做效率。
JSONP算做JSON的一種」使用模式」,可用於解決主流瀏覽器的跨域數據訪問的問題。因爲CORS的支持,咱們能夠簡單的將數據封裝成一個js腳本請求,固然咱們在jquery中會用到。
function logResults(json){ console.log(json); } $.ajax({ url: "https://yourapi.com/api", dataType: "jsonp", jsonpCallback: "logResults" });
聊Comet咱們還得說下短輪詢,因爲某些特定的業務需求,好比通知,咱們須要有及時的數據更新,咱們可以想到的就是使用setInterval
每隔必定時間好比10s去獲取一次請求,從而作到一些通知更新,可是這並不一種高效的作法,這會增長服務器的請求數量。這個時候有了另一種概念,「反向Ajax」,由服務器進行數據推送, Comet可以讓信息近乎實時的被推送到頁面上,很是適合要求實時性的獲取的數據的頁面。
如圖所示,就是一個簡單的Comet模型,就是數據請求後掛起,直到有數據響應推送到客戶端,這個時候客戶端再發起一個新的鏈接。
這樣相對來講能夠減小必定數量的請求,以及數據的及時響應,從而必定意義的實現所謂推送。
一個簡單的PHP Demo代碼,就是咱們須要這端代碼一直運行着…
while(true) { set_time_limit(0); echo 'data'; flush(); b_flush(); sleep(3); }
JavaScript:
function createStreamingClient(url,progress,finished){ var xhr=new XMLHttpRequest(),received=0; xhr.open("get",url,true); xhr.onreadystatechange=function(){ var result; if(xhr.readyState==3){ result=xhr.responseText.substring(received); received+=result.length; progress(result); }else if(xhr.readyState==4){ finished(xhr.responseText); } }; xhr.send(null); return xhr; } // var client = createStreamingClient(url,fuc1,func2)
SSE是圍繞只讀Comet交互推出的API或者模式。SSE API用於建立到服務器的單向鏈接,服務器經過這個鏈接能夠發送任意數量的數據。服務器響應的MIME類型必須是text/event-stream
,並且是瀏覽器中的Javascript API能解析的格式輸出。
現對於Comet,咱們能夠看出咱們只進行了一次鏈接,而後服務端會去控制數據的響應,從而發送給客戶端。這樣相對來講,可是如同定義的描述,這種只適合只讀數據的情形。好比一些通知和狀態碼這樣的。SEE的使用很是簡單,只須要掌握這幾個api就行:
var es = new EventSource('http://your.api.com' function listener(event) { console.log(event.data); } // 建立一個SSE鏈接 es.addEventListener("open", listener); // 響應獲取消息的事件 es.addEventListener("message", listener); // 發生錯誤 es.addEventListener("error", listener);
注意:若是在回話過程當中碰見錯誤後,默認程序會從新發起一次新的鏈接,從而防止掛掉就再也不響應了
服務端(node,php)的代碼,能夠參考:https://github.com/Yaffle/EventSource
HTML5 WebSocket 設計出來的目的就是要取代輪詢和 Comet 技術,使客戶端瀏覽器具有像 C/S 架構下桌面系統的實時通信能力。 瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。也就是咱們可使用web技術構建實時性的程序好比聊天遊戲等應用。
其實Web Sockets 的API不多,就下面這些
websocket = new WebSocket("ws://your.socket.com:9001"); // 大開 websocket.onopen = function(evt) { /* do stuff */ }; //on open event // 當web socket關閉 websocket.onclose = function(evt) { /* do stuff */ }; // 進行通訊時 websocket.onmessage = function(evt) { /* do stuff */ }; // 發生錯誤時 websocket.onerror = function(evt) { /* do stuff */ }; // 向服務器發發送消息 websocket.send(message); //send method websocket.close(); //close method
對於服務端的話,PHP支持了不少socket 相關api,可是咱們可使用更加成熟的框架(實用)好比phpsocket.io,Ratchet.固然node.js寫 socket也很是駕輕就熟,node.js對高併發支持相對較好,可使用http://socket.io/。
服務端大概會作下面的事情: + 建立一個socket + 綁定地址和端口 + 監聽進入的鏈接 + 接收新的鏈接 + web socket 握手 + 解碼數據
注意:SSE和 Web Sockets 都是新的api,須要你們考慮兼容性*
說了那麼多簡單總結下,你們想明白幾點就好了,客戶端與服務端誰先主動,是否強調數據的實時性。