前端跨域的解決方式
前端與服務端數據交互時,涉及到跨域的一些問題。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一起使用,實現強大的新體驗功能。
前端跨域的解決方式