AJAX 跨域請求(轉發)

什麼是JSONP:JSONP(JSON with Padding)是一個非官方的協議,它容許在服務器端集成Script tags返回至客戶端,經過javascript callback的形式實現跨域訪問。
JSONP有什麼用:因爲同源策略的限制,XmlHttpRequest只容許請求當前源(域名、協議、端口)的資源,爲了實現跨域請求,能夠經過script標籤實現跨域請求,而後在服務端輸出JSON數據並執行回調函數,從而解決了跨域的數據請求。
如何使用JSONP:下邊這一DEMO其實是JSONP的簡單表現形式,在客戶端聲明回調函數以後,客戶端經過script標籤向服務器跨域請求數據,而後服務端返回相應的數據並動態執行回調函數。javascript

<script type="text/javascript">  
    function jsonpCallback(result) {  
        //alert(result);  
        for(var i in result) {  
            alert(i+":"+result[i]);//循環輸出a:1,b:2,etc.  
        }  
    }  
    var JSONP=document.createElement("script");  
    JSONP.type="text/javascript";  
    JSONP.src="http://.../services.php?callback=jsonpCallback";  
    document.getElementsByTagName("head")[0].appendChild(JSONP);  
</script> 

服務端PHP代碼 (services.php):php

//服務端返回JSON數據  
$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);  
$result=json_encode($arr);  
//echo $_GET['callback'].'("Hello,World!")';  
//echo $_GET['callback']."($result)";  
//動態執行回調函數  
$callback=$_GET['callback'];  
echo $callback."($result)"; 

若是將上述JS客戶端代碼用jQuery的方法來實現,也很是簡單。
$.getJSON
$.ajax
$.get
客戶端JS代碼在jQuery中的實現方式1:java

<script type="text/javascript">  
    $.getJSON("http://.../services.php?callback=?",  
    function(result) {  
        for(var i in result) {  
            alert(i+":"+result[i]);//循環輸出a:1,b:2,etc.  
        }  
    });  
</script>  

客戶端JS代碼在jQuery中的實現方式2:ajax

<script type="text/javascript">  
    $.ajax({  
        url:"http://.../services.php",  
        dataType:'jsonp',  
        data:'',  
        jsonp:'callback',  
        success:function(result) {  
            for(var i in result) {  
                alert(i+":"+result[i]);//循環輸出a:1,b:2,etc.  
            }  
        },  
        timeout:3000  
    });  
</script>  

客戶端JS代碼在jQuery中的實現方式3:json

<script type="text/javascript">  
    $.get('http://.../services.php?callback=?', {name: encodeURIComponent('tester')}, function (json) { for(var i in json) alert(i+":"+json[i]); }, 'jsonp');  
</script>  

其中 jsonCallback 是客戶端註冊的,獲取 跨域服務器 上的json數據 後,回調的函數。
http://.../services.php?callback=jsonpCallback
這個 url 是跨域服務 器取 json 數據的接口,參數爲回調函數的名字,返回的格式爲
jsonpCallback({msg:'this is json data'}) 跨域

Jsonp原理
首先在客戶端註冊一個callback, 而後把callback的名字傳給服務器。
此時,服務器先生成 json 數據。
而後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的參數 jsonp.
最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標籤,並執行返回的 javascript 文檔,此時數據做爲參數,傳入到了客戶端預先定義好的 callback 函數裏.(動態執行回調函數)。瀏覽器

使用JSON的優勢在於
比XML輕了不少,沒有那麼多冗餘的東西。
JSON也是具備很好的可讀性的,可是一般返回的都是壓縮事後的。不像XML這樣的瀏覽器能夠直接顯示,瀏覽器對於JSON的格式化的顯示就須要藉助一些插件了。
在JavaScript中處理JSON很簡單。
其餘語言例如PHP對於JSON的支持也不錯。安全

JSON也有一些劣勢
JSON在服務端語言的支持不像XML那麼普遍,不過JSON.org上提供不少語言的庫。
若是你使用eval()來解析的話,會容易出現安全問題。
儘管如此,JSON的優勢仍是很明顯的。他是Ajax數據交互的很理想的數據格式。服務器

主要提示
JSONP 是構建 mashup 的強大技術,但不幸的是,它並非全部跨域通訊需求的萬靈藥。它有一些缺陷,在提交開發資源以前必須認真考慮它們。
第一,也是最重要的一點,沒有關於 JSONP 調用的錯誤處理。若是動態腳本插入有效,就執行調用;若是無效,就靜默失敗。失敗是沒有任何提示的。例如,不能從服務器捕捉到 404 錯誤,也不能取消或從新開始請求。不過,等待一段時間尚未響應的話,就不用理它了。(將來的 jQuery 版本可能有終止 JSONP 請求的特性)。
JSONP 的另外一個主要缺陷是被不信任的服務使用時會很危險。由於 JSONP 服務返回打包在函數調用中的 JSON 響應,而函數調用是由瀏覽器執行的,這使宿主 Web 應用程序更容易受到各種攻擊。若是打算使用 JSONP 服務,瞭解它能形成的威脅很是重要。app

相關文章
相關標籤/搜索