編輯中,尚未完稿。。。2017.7.14 1345
很多前端開發出來的HTML5可能對於後臺開發者來說,並不是很清楚,也許像我一樣一知半解。而且真的讓人很糊塗的地方就是前端的JS如何與後端的資料庫進行雙向通訊,互動資料。
一種解釋認為簡單點說,這就是前端技術與後端技術溝通,根據業務定義互動介面,互動介面的的形式可能包含:
1、後端將資料輸出到HTML頁面,在JS控制邏輯中需要訪問資料時可以從HTML中取得。
2、定義前後端請求的介面,一般是AJAX介面,如果存在跨域問題或一些特殊的業務場景,可能也會使用JSONP或者其他方式,總之,不論是何種方式請求,目的都是動態的請求資料,然後根據返回資料重新整理頁面內容。返回資料的格式現在主流是使用JSON格式,但是也不排除一些特殊的業務場景需要是使用XML或其他格式的資料。
對於我一樣的新手,跨域請求的例子可參考Ajax 跨域請求、如何解決ajax跨域問題(轉)。
總之非跨域請求限制比較少,但跨域請求的限制很多。
最初XHR
物件是不能跨域的,但新版本的瀏覽器允許跨域,但需要服務端對當前網站開許可權。
在不允許跨域的年代,都是通過某些hack
的方法來實現跨域的。通常是藉助一些天生能夠跨域的元素:script, img, iframe
,這些元素裡面script
最好,因為可以很方便地執行JS程式碼,從而能夠對返回的資料進行處理。
跨域的優勢是能充分利用分散式叢集系統,使某些服務壓力可以分散到多臺伺服器上。但資料互動的安全性上有一定影響。
不跨域的優勢是前臺頁面和後臺服務都在一個伺服器下,安全性高,但但不能分攤負載。
目前計算機行業正在向高整合,多併發,低耦合的方向發展。所有基礎服務以介面的方式提供是很好的一種方案(像百度地圖,微信,支付寶都有服務介面),基礎服務和中介軟體之間的互動也可能採用服務呼叫的方式,這些問題就牽扯到跨域,處理好跨域和安全的平衡點是這類整合系統的需要重點權衡的方面之一。
現在的網際網路技術發展的越來越快,我們在開發過程中遇到的問題也越來越多。比如當我們需要進行跨域訪問資料的時候該如何進行開發?本篇博文就記述如何使用Ajax進行跨域訪問呼叫資料。
1、非跨域呼叫
我們用到的最多是這樣的方式,也就是非跨域的進行訪問,只是簡單的在我們的網頁中進行Ajax使用即可。如下面程式碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/** * 非跨域請求方式
*/ function feikuayu() {
$.ajax({
type: "post" ,
url: platformUrl + "/security/modifyPwd" ,
data: $( `#updatepwdform` ).serialize(),
dataType: "json" ,
success: function (data) {
$( "#updatepwd_btn" ).click();
$.toast( "修改成功,系統即將退出,請重新登入" , 1500);
},
error: function () {
$.toast( "網路異常" , 1500);
}
});
} |
2、跨域請求
在我們進行跨域請求時需要改變ajax固定引數:
dataType:”jsonp”,
crossDomain:true,
jsonpCallback:”jsonpCallbackFun”,
jsonp:”callback”,
且後臺返回的資料格式必須是:jsonpCallbackFun(json資料); 這裡的jsonpCallbackFun是你自定義的回撥函式方法名。
程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/** * 跨域請求方式
*/ function kuayu() {
$.ajax({
type: "post" ,
url: platformUrl + "/security/modifyPwd" ,
data: params,
dataType: "jsonp" ,
crossDomain: true ,
jsonpCallback: "jsonpCallbackFun" ,
jsonp: "callback" ,
success: function (data) {
if (data.result == 1) {
$( "#updatepwd_btn" ).click();
$.toast( "修改成功,系統即將退出,請重新登入" , 1500);
setTimeout( "logout()" , 1600);
} else if (data.result == 2) {
$.toast(data.msg, 1500);
} else {
$.toast( "修改失敗" , 1500);
}
},
error: function () {
$.toast( "網路異常" , 1500);
}
});
} |
兩種協議型別
SOAP
我們知道Android網路通訊的方式有兩種:基於Socket和基於HTTP。基於HTTP又包括兩種程式設計方式:HttpUrlConnection和HttpClient。
HttpURLConnection和SOAP完全是兩回事,前者是網路程式設計方式(傳送請求、獲得應答),後者是一種資料傳輸協議,由於其基於XML,可以穿越防火牆,所以在Web Service中大受歡迎。
當比較HttpURLConnection與之之間的區別時,可以得知:
二者區別是,HttpURLConnection實現網路連線資料傳輸,SOAP以XML方式定義傳輸的資料格式(當然SOAP不光光定義資料格式,還包括方法、訊息很多格式)。
其實將HTTP和SOAP放在一起比較更有意義,借用網路上的一段文字:
不同:都是底層的通訊協議,請求包的格式不同而已,soap包是XML格式,http純文字格式。
關係:SOAP是個通訊協議, SOAP在HTTP協議的基礎上,把編寫成XML的REQUEST引數, 放在HTTP BODY上提交個WEB SERVICE伺服器(SERVLET,ASP什麼的) 處理完成後,結果也寫成XML作為RESPONSE送回使用者端, 為了使使用者端和WEB SERVICE可以相互對應,可以使用WSDL作為這種通訊方式的描述檔案,利用WSDL工具可以自動生成WS和使用者端的框架檔案,SOAP具備把複雜物件序列化捆綁到XML裡去的能力。
其實SOAP最早是針對RPC的一種解決方案,簡單物件訪問協議,很輕量,同時作為應用協議可以基於多種傳輸協議來傳遞訊息(Http,SMTP等)。但是隨著SOAP作為WebService的廣泛應用,不斷地增加附加的內容,使得現在開發人員覺得SOAP很重,使用門檻很高。在SOAP後續的發展過程中,WS-*一系列協議的制定,增加了SOAP的成熟度,也給SOAP增加了負擔。
REST
REST其實並不是什麼協議也不是什麼標準,而是將Http協議的設計初衷作了詮釋,在Http協議被廣泛利用的今天,越來越多的是將其作為傳輸協議,而非原先設計者所考慮的應用協議。SOAP型別的WebService就是最好的例子,SOAP訊息完全就是將Http協議作為訊息承載,以至於對於Http協議中的各種引數(例如編碼,錯誤碼等)都置之不顧。其實,最輕量級的應用協議就是Http協議。Http協議所抽象的get,post,put,delete就好比資料庫中最基本的增刪改查,而網際網路上的各種資源就好比資料庫中的記錄(可能這麼比喻不是很好),對於各種資源的操作最後總是能抽象成為這四種基本操作,在定義了定位資源的規則以後,對於資源的操作通過標準的Http協議就可以實現,開發者也會受益於這種輕量級的協議。
自己理解的將REST的思想歸結以下有如下幾個關鍵點:
1.面向資源的介面設計
所有的介面設計都是針對資源來設計的,也就很類似於我們的物件導向和麵向過程的設計區別,只不過現在將網路上的操作實體都作為資源來看待,同時URI的設計也是體現了對於資源的定位設計。後面會提到有一些網站的API設計說是REST設計,其實是RPC-REST的混合體,並非是REST的思想。
2.抽象操作為基礎的CRUD
這點很簡單,Http中的get,put,post,delete分別對應了read,update,create,delete四種操作,如果僅僅是作為對於資源的操作,抽象成為這四種已經足夠了,但是對於現在的一些複雜的業務服務介面設計,可能這樣的抽象未必能夠滿足。其實這也在後面的幾個網站的API設計中暴露了這樣的問題,如果要完全按照REST的思想來設計,那麼適用的環境將會有限制,而非放之四海皆準的。
3.Http是應用協議而非傳輸協議
這點在後面各大網站的API分析中有很明顯的體現,其實有些網站已經走到了SOAP的老路上,說是REST的理念設計,其實是作了一套私有的SOAP協議,因此稱之為REST風格的自定義SOAP協議。
4.無狀態,自包含
這點其實不僅僅是對於REST來說的,作為介面設計都需要能夠做到這點,也是作為可擴充套件和高效性的最基本的保證,就算是使用SOAP的WebService也是一樣。
參考文章