1. 程式人生 > >前端跨域的解決方式

前端跨域的解決方式

指定 模式 輸出 enc oauth t對象 TTT 註意 pos

前端與服務端數據交互時,涉及到跨域的一些問題。JavaScript出於安全的考慮,禁止了跨域調用其他頁面的對象,也即同源策略限制了一個源(origin)中加載文本或腳本與來自其它源(origin)中資源的交互方式。

什麽是跨域?

如果兩個頁面擁有相同的協議(protocol),端口(如果指定),和主機,那麽這兩個頁面就屬於同一個源(origin),JavaScript允許這種同源頁面的數據互相通信。

帶來的麻煩,以及解決方案

同源策略讓JavaScript或Cookie只能訪問同域下的內容,但在實際開發項目時會不可避免的要進行跨域操作,因此給前端帶來了麻煩,跨域能力也算是前端工程師的基本功之一,對於端口和協議的不同,只能通過後臺來解決了,下面主要說說主機不同情況實現跨域。

神器JSONP

JSONP是比較流行的跨域處理方式,網絡上的定義:JSONP是資料格式JSON的一種使用模式,可以讓網頁從別的網域要資料,原理是HTML的script標簽可以加載並執行其他域JS文件。站點B把要提供的數據作為參數傳給一個站點A定義的全局函數,站點A引用這個文件就可以跨域獲取數據了,A站還可以把少量參數放在script標簽的src裏提交給B站。外鏈JS這種方案只支持GET,受IE下url長度不能超過2083個字節的限制和出於安全考慮,一般不用來提交數據。

JSONP實際上就是被包含在一個回調函數中的JSON,例如callback({"name":"zhangsan"});

因此我們可以知道JSONP有兩部分組成:回調函數和數據。回調函數是當響應到來時應該在頁面中調用的函數,而數據就是傳入回調函數中的JSON數據,需要註意的是這個回調函數一定要讓後端開發人員處理包裹,否則只能獲取json數據,不能使用。

在js中,不可以直接用XMLHttpRequest請求不同域上的數據。但我們知道在頁面上引入不同域上的js腳本文件是被允許的,JSONP就正是利用這個特性來實現的,例如:

<script src="http://jd.com/data.php?callback=dosomething"></script>

<script type="text/javascript">

function dosomething(jsondata){

  console.log(jsondata);

}

</script>

js文件載入成功後,會執行我們在url參數中指定的函數(dosomething),並且會把我們需要的json數據(jsondata)作為參數傳入。所以再次強調jsonp是需要服務器端的頁面進行相應的配合的。

<?php

  $callback=$_GET[‘callback‘];//得到回調函數名

  $data={‘name‘:‘張三‘,sex:‘男‘,age:‘15‘};//要返回的數據

  echo $callback.‘(‘.json_encode($data).‘)‘;//輸出

?>

最終輸出結果為:dosomething({‘name‘:‘張三‘,sex:‘男‘,age:‘15‘});

如果你使用jquery或者zepto,那麽通過它封裝的方法就能很方便的來進行JSONP操作了。

JSONP的優點是:

①:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制

②:它的兼容性更好,在老版本的瀏覽器中可以運行,不需要XMLHttpRequest或ActiveX的支持

③:它在請求完畢後可以通過調用callback的方式回傳結果,方便調用。

JSONP的缺點則是:

①:它只支持GET請求而不支持POST等其他類型的HTTTP請求,不能提交大量數據

②:它只支持跨域HTTP請求這總情況,不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題。

先進的CORS

W3C推薦了一種更為先進的機制,也就是CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問跨域資源時,瀏覽器與服務器應該如何溝通。CORS背後的基本思想就是使用自定義的HTTP頭部,讓服務器能聲明哪些來源可以通過瀏覽器訪問該服務器上的資源,從而決定請求或響應是應該成功還是失敗,CORS本身並非絕對很安全,可利用OAuth2措施來加強保障。

與JSONP相比較,CORS支持所有類型的HTTP請求,且開發者可以使用原生普通的XMLHttpRequest對象發起請求和獲得數據,配合新的JSAPI一起使用,實現強大的新體驗功能。

前端跨域的解決方式