JSONP原理及JQUERY JSONP的使用

JSONP原理

JSON和JSONP

  JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。對於JSON你們應該是很瞭解了吧,不是很清楚的朋友能夠去json.org上了解下,簡單易懂。javascript

  JSONP是JSON with Padding的略稱。它是一個非官方的協議,它容許在服務器端集成Scripttags返回至客戶端,經過javascriptcallback的形式實現跨域訪問(這僅僅是JSONP簡單的實現形式)。html

  JSONP就像是JSON+Padding同樣(Padding這裏咱們理解爲填充),咱們先看下面的小例子而後再詳細介紹。前端

同源策略

在JavaScript中,有一個很重要的安全性限制,被稱爲「Same-OriginPolicy」(同源策略)。這一策略對於JavaScript代碼可以訪問的頁面內容作了很重要的限制,即JavaScript只能訪問與包含它的文檔在同一域下的內容。java

根據這個策略,在baidu.com下的頁面中包含的JavaScript代碼,不能訪問在google.com域名下的頁面內容;甚至不一樣的子域名之間的頁面也不能經過JavaScript代碼互相訪問。對於Ajax的影響在於,經過XMLHttpRequest實現的Ajax請求,不能向不一樣的域提交請求,例如,在abc.example.com下的頁面,不能向def.example.com提交Ajax請求,等等。然而,當進行一些比較深刻的前端編程的時候,不可避免地須要進行跨域操做,這時候「同源策略」就顯得過於苛刻。ajax

然而html中有一些元素是不存在跨域問題的如:script,iframe等元素,利用這些元素,就能很好的解決這個問題.數據庫

JSONP的實現方式

利用在頁面中建立<script>節點的方法向不一樣域提交HTTP請求,這項技術就能夠解決跨域提交Ajax請求的問題。編程

先看一個簡單例子json

example1.com有這樣一個方法跨域

<script type="text/javascript">
//回調函數
function callback(data) {
  //顯示客戶信息在A頁面上;
}
</script>

//經過加載example2的JS文件來達到函數調用和數據傳遞
<script type="text/javascript" src="http://example2.com/test.js"></script>

 example2.com的test.js內容以下瀏覽器

//回調函數
callback({name:"張三"});

以上這種方法只是一個簡單實現緣由的例子,現實中咱們的數據和回調也不會都寫死在JS中的,因此咱們要想辦法將這些靜態的東西動態生成就能夠了.只要將example1.com srcipt 地址改成一個能動態生成JS調用方法的服務地址便可.如:

<script type="text/javascript" src="http://example2.com/test.do"></script>

test.do Controller直接返回以下

callback(數據庫客戶信息的JSON對象);

例子以下:固然對<script type="text/javascript"src="http://example2.com/test.do">的調用,你也能夠動態來建立script標籤完成,這樣就更靈活一些.

倘若要實現一個需求,某個網站a.com上顯示的客戶信息來自於其它網站b.com,顯然經過AJAX請求去取數據是不能作到的,由於存在同源策略.

A網站的前臺實現:

<script type="text/javascript">
    //回調函數
    function displayCustomer(data) {
         alert(data);
         //將客戶信息顯示在A.com的頁面上...
     }
    ​
    window.onload = function(){

    ​     //添加<script>標籤的方法
         function createScript(src){
             var script = document.createElement('script');
             script.setAttribute("type","text/javascript");
             script.src = src;
             document.body.appendChild(script);
         }
    }
</script>

createScript("http://B.com/search.do?&callback=displayCustomer");
  • B網站的後臺實現:
@Controller
public classJsonpRest {
    @RequestMapping(value = "/test.do",method = RequestMethod.GET)
    public @ResponseBody Stringlist(HttpServletRequest request) {
        returnrequest.getParameter("callback")+"({name:'張三',age:18})";
    }
}

JSONP的優勢是:

它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中均可以運行,不須要XMLHttpRequest或ActiveX的支持;而且在請求完畢後能夠經過調用callback的方式回傳結果。

JSONP的缺點則是:

  1. 它只支持GET請求而不支持POST等其它類型的HTTP請求;它只支持跨域HTTP請求這種狀況,不能解決不一樣域的兩個頁面之間如何進行JavaScript調用的問題。
  2. 沒有關於 JSONP調用的錯誤處理。若是動態腳本插入有效,就執行調用;若是無效,就靜默失敗。失敗是沒有任何提示的。例如,不能從服務器捕捉到404 錯誤,也不能取消或從新開始請求。不過,等待一段時間尚未響應的話,就不用理它了。

JQUERY對JSONP的支持

從JQery 1.2之後,就開始支持JSONP的調用。JQuery對前臺作了很好的處理如自動生成全局回調函數等,但後臺還須要開發人員本身實現.

$.getJSON("http://跨域的dns/xxx.do?callback=?",function(json){          
    // 業務邏輯執行代碼
});

請求URL 
http://xxx.com/rest.do?callba..._1332575486681&_=1393510789026

$.ajax({
       url:"http://xxx.com/rest.do",
        dataType:"jsonp",   //必須指定

        jsonp : "c",        //若不指定則默認爲callback

        jsonpCallback:"test",//若不指定則Jquery本身生成隨機的名稱
        success:function(data){
            //業務邏輯執行代碼
        }
});

請求URL http://xxx.com/rest.do?c=test&_=1393510789026

  1. 當dataType爲JSONP時,JQUERY會爲用戶生成一個全局函數名稱爲jsonpCallback參數的值,這個函數內部調用了success方法JQUERY的實現原理及步驟
  2. 以GET方式請求目標地址,並在URL中拼接以jsonp參數值爲key,以jsonpCallback值爲value的參數
  3. 請求返回回調函數數據
  4. 觸發調用全局的回調函數,在全局函數回調中調用success方法並將數據傳遞給success方法
相關文章
相關標籤/搜索