JSONP原理
JSONP的最基本的原理是:動態添加一個<script>標簽,而script標簽的src屬性是沒有跨域的限制的。這樣說來,這種跨域方式其實與ajax XmlHttpRequest協議無關了。
JSONP(JSON with Padding)是json的一種"使用模式",可用於解決主流瀏覽器的跨域數據訪問的問題。由於同源策略,一般來說位於 server1.example.com 的網頁無法與不是 server1.example.com的服務器溝通,而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。
使用:
1. 在客戶端調用提供JSONP支持的URL Service,獲取JSONP格式數據。
比如客戶想訪問http://www.yiwuku.com/myService.aspx?jsonp=callbackFunction
假設客戶期望返回JSON數據:["customername1","customername2"]
那么真正返回到客戶端的Script Tags: callbackFunction(["customername1","customername2"])
可能的調用方式:
2.在客戶端寫callbackfunction函數的實現
3.頁面展示
4.最終page code
體現:jquery下jsoncallback=?,其中“?”會自動替代function(data)函數。
2.$.ajax
如何在服務器端實現對JSONP支持
這僅僅需要把服務的JSON數據轉換成想要的script tags的形式就可以了,格式可以自已定義,畢竟這是個非官方的協議。
可參考:Implement JSONP in your Asp.net Application
注:Callback僅僅是JSONP的簡單實現,可以根據具體需要實現更復雜的功能,比如可以在客戶端動態集成更多的變量數據來完成分頁功能。
return request.getParameter("jsoncallback")+"("+JsonString+")";
返回內容像:jsonp1382016430883([{"id":1,"title":"XXXX"},{"id":2,"title":"YYYYY"}])
JSONP的優點是:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中都可以運行,不需要XMLHttpRequest或ActiveX的支持;並且在請求完畢后可以通過調用callback的方式回傳結果。
JSONP的缺點則是:它只支持GET請求而不支持POST等其它類型的HTTP請求;它只支持跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題。
例子:如在當前網址ip1向ip2中提交get請求,我們可以將以下代碼放在ip1中:
Var elescript=document.createElement(“script”);
elescript.type=”text/javascript”;
elescript.src=”ip2“;
document.Getelementsbytagname(“head”)[0].appendchild(elescript);
再如:var qsData = {'searchWord':$("#searchWord").attr("value"),'currentUserId':
$("#currentUserId").attr("value"),'conditionBean.pageSize':$("#pageSize").attr("value")};
$.ajax({
async:false,
url: http://跨域的dns/document!searchJSONResult.action,
type: "GET",
dataType: 'jsonp',
jsonp: 'jsoncallback',
data: qsData,
timeout: 5000,
beforeSend: function(){
//jsonp 方式此方法不被觸發.原因可能是dataType如果指定為jsonp的話,就已經不是ajax事件了
},
success: function (json) {//客戶端jquery預先定義好的callback函數,成功獲取跨域服務器上的json數據后,會動態執行這個callback函數
if(json.actionErrors.length!=0){
alert(json.actionErrors);
}
genDynamicContent(qsData,type,json);
},
complete: function(XMLHttpRequest, textStatus){
$.unblockUI({ fadeOut: 10 });
},
error: function(xhr){
//jsonp 方式此方法不被觸發.原因可能是dataType如果指定為jsonp的話,就已經不是ajax事件了
//請求出錯處理
alert("請求出錯(請檢查相關度網絡狀況.)");
}
});
有時也會
$.getJSON("http://dns/document!searchJSONResult.action?name1="+value1+"&jsoncallback=?",
function(json){
if(json.屬性名==值){
// 執行代碼
}
});
在響應端(http://跨域的dns/document!searchJSONResult.action),通過 jsoncallback = request.getParameter("jsoncallback") 得到jquery端隨后要回調的js function name:jsonp1236827957501 然后 response的內容為一個Script Tags:"jsonp1236827957501("+按請求參數生成的json數組+")"; jquery就會通過回調方法動態加載調用這個js tag:jsonp1236827957501(json數組); 這樣就達到了跨域數據交換的目的。