动态

详情 返回 返回

JSONP原理及JQUERY JSONP的使用 - 动态 详情

JSONP原理

JSON和JSONP

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

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

  JSONP就像是JSON+Padding一樣(Padding這裏我們理解為填充),我們先看下面的小例子然後再詳細介紹。

同源策略

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

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

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

JSONP的實現方式

利用在頁面中創建<script>節點的方法向不同域提交HTTP請求,這項技術就可以解決跨域提交Ajax請求的問題。

先看一個簡單例子

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方法
user avatar pantao 头像 linlinma 头像 front_yue 头像 littlelyon 头像 zourongle 头像 linx 头像 anchen_5c17815319fb5 头像 hard_heart_603dd717240e2 头像 shuirong1997 头像 xiaolei_599661330c0cb 头像 assassin 头像 DolphinScheduler 头像
点赞 105 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.