1、同源政策
浏覽器有一個很重要的概念——同源政策(Same-Origin Policy)。所謂同源是指,域名,協定,端口相同。不同源的用戶端腳本(javascript、ActionScript)在沒明确授權的情況下,不能讀寫對方的資源。
2、JSONP
JSONP(JSON with Padding)是JSON的一種”使用模式”,可用于解決主流浏覽器的跨域資料通路的問題。由于同源政策,一般來說位于 server1.example.com 的網頁無法與不是 server1.example.com的伺服器溝通,而 HTML 的script 元素是一個例外。利用
3、具體實作
那下面我們來看看jquery 是怎麼處理跨域請求的,不多說,直接貼代碼,先看個詳細版的:
<script type="text/javascript">
function getResult(data){
alert("through jsonp,receive data from other domain : "+data.result);
}
function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/other.jsp',
type:'post',
data:{'params':'fromjsonp'},
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回調函數名的參數名(一般預設為:callback)
jsonpCallback:"getResult",//自定義的jsonp回調函數名稱,預設為jQuery自動生成的随機函數名,也可以不寫這個參數,jQuery會自動為你處理資料
success: function(data){
},
error: function(){
alert('fail');
}
});
}
</script>
<body>
<input type="button" value="jsonp" onclick="jsonp_fun()"/>
</body>
這裡的jsonCallback,回調函數設定為getResult,那麼傳回後會先調用getResult函數中的代碼,再調用success函數中的代碼,一般情況下,不用定義getResult函數,同樣jsonCallback不需要設定,那麼就隻執行success中的代碼,也就跟平時的ajax一樣用。
下面我們來看看正式的工作實作:
function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/other.jsp',
type:'post',
data:{'params':'fromjsonp'},
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回調函數名的參數名(一般預設為:callback)
success: function(data){
alert("through jsonp,receive data from other domain : "+data.result);
},
error: function(){
alert('fail');
}
});
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String params = request.getParameter("params");
String callback = request.getParameter("callback");
// 經過該接口一系列操作,然後得到data,将data傳回給調用者
String data = "{\"result\":\""+params+"\"}";
out.println(callback + "("+data+")");
%>
這裡沒有指定jsonpCallback,實際上jquery底層拼裝了一個函數名。
補充:
1、ajax和jsonp這兩種技術在調用方式上“看起來”很像,目的也一樣,都是請求一個url,然後把伺服器傳回的資料進行處理,是以jquery和ext等架構都把jsonp作為ajax的一種形式進行了封裝;
2、但ajax和jsonp其實本質上是不同的東西。ajax的核心是通過XmlHttpRequest擷取非本頁内容,而jsonp的核心則是動态添加
3、是以說,其實ajax與jsonp的差別不在于是否跨域,ajax通過服務端代理一樣可以實作跨域,jsonp本身也不排斥同域的資料的擷取。
4、還有就是,jsonp是一種方式或者說非強制性協定,如同ajax一樣,它也不一定非要用json格式來傳遞資料,如果你願意,字元串都行,隻不過這樣不利于用jsonp提供公開服務。
另外補充最後一點:
Jsonp能解決的ajax跨域請求其實相當有限,推薦還是使用CROS,因為Jsonp的請求隻能是get,雖然在上面示範中,我設定的type為post,但是實際上發的請求還是get,是以也就造成了萬一我的請求是post了,怎麼辦,要是跨域ajax檔案上傳了,怎麼辦,這點希望大家注意:
這裡寫圖檔描述
參考:http://blog.csdn.net/saytime