閱讀467 返回首頁    go 阿裏雲 go 技術社區[雲棲]


ajax實現JSONP跨域

AJAX的一大限製是不允許跨域請求。 不過通過使用JSONP來實現。JSONP是一種通過腳本標記注入的方式,它是可以引用跨域URL的js腳本,不過需要提供一個回調函數(必須在您自己的頁麵上),因此,你可以自己處理結果

什麼是跨域

簡單的說,出於安全方麵的考慮,頁麵中的JavaScript無法訪問其他服務器上的數據,即“同源策略”。而跨域就是通過某些手段來繞過同源策略限製,實現不同服務器之間通信的效果

具體策略限製情況可看下表:

URL 說明 允許通信
https://www.a.com/a.js
https://www.a.com/b.js
同一域名下 允許
https://www.a.com/lab/a.js
https://www.a.com/script/b.js
同一域名下不同文件夾 允許
https://www.a.com:8000/a.js
https://www.a.com/b.js
同一域名,不同端口 不允許
https://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同協議 不允許
https://www.a.com/a.js
https://127.0.0.100/b.js
域名和域名對應ip 不允許
https://www.a.com/a.js
https://script.a.com/b.js
主域相同,子域不同 不允許
https://www.a.com/a.js
https://a.com/b.js
同一域名下不同二級域名 不允許
https://www.a.com/a.js
https://www.b.com/b.js
不同域名 不允許

什麼是JSONP?

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,而JSONP(JSON with Padding)則是JSON 的一種“使用模式”,通過這種模式可以實現數據的跨域獲取

JSONP的應用

JSONP在開放API中可以起到非常重要的作用,開放API是運用在開發者自己的應用上,而許多應用往往是在開發者的服務器上,因此跨域請求數據成為開發者們所需要解決的一大問題,廣大開放平台應該實現對JSONP的支持,這一點新浪微博開放平台便做的非常好(雖然某些API裏沒有說明,但實際上是可以使用JSONP方式調用的)

JSONP跨域的原理

同源策略下,在某個服務器下的頁麵是無法獲取到該服務器以外的數據的,但img、iframe、script等標簽是個例外,這些標簽可以通過src屬性請求到其他服務器上的數據。利用script標簽的開放策略,我們可以實現跨域請求數據,當然,也需要服務端的配合。當我們正常地請求一個JSON數據的時候,服務端返回的是一串JSON類型的數據,而我們使用JSONP模式來請求數據的時候,服務端返回的是一段可執行的JavaScript代碼

舉個例子,假如需要從服務器(https://www.a.com/user?id=123)獲取的數據如下:

{"id": 123, "name" : 張三, "age": 17} 

那麼,使用JSONP方式請求(https://www.a.com/user?id=123?callback=foo)的數據將會是如下:

foo({"id": 123, "name" : 張三, "age": 17});

當然,如果服務端考慮得更加充分,返回的數據可能如下:

try{foo({"id": 123, "name" : 張三, "age": 17});}catch(e){}

這時候我們隻要定義一個foo()函數,並動態地創建一個script標簽,使其的src屬性為https://www.a.com/user?id=123?callback=foo

function executeJsonp(url){
  var eleScript= document.createElement("script");
  eleScript.type = "text/javascript";
  eleScript.src = url;
  document.getElementsByTagName("head")[0].appendChild(eleScript);
}
function foo(data){
    for(var p in data){
      console.log(data[p]);
    }
}
var url = "https://www.a.com/user?id=123?callback=foo";
executeJsonp(url)

在jQuery中如何通過JSONP來跨域獲取數據

第一種方法是在ajax函數中設置dataType為'jsonp':


$.ajax({ 
    type:"get", 
         data:"random="+Math.random(), 
         url:url, 
         dataType:"jsonp", 
         jsonp:"callback", 
         success:function(data){ //處理data數據
         $.each(data, function(key, val) { 
            $("#myDiv").html($("#myDiv").html()+val.cvalue+"</br>"); 
         }); 
        } 
}); 

第二種方法是利用getJSON來實現,隻要在地址中加上callback=?參數即可:

jQuery.getJSON("https://search.twitter.com/search.json?callback=?",{ 
    q: "Arsenal" 
},function(tweets) { 
    console.info("Twitter returned: ",tweets); 
});

也可以簡單地使用getScript方法:

//此時也可以在函數外定義foo方法
function foo(data){}//處理data數據
$.getJSON('https://www.a.com/user?id=123&callback=foo');

jquery中的ajax方法怎樣通過JSONP進行遠程調用

$.ajax的參數

type:請求方式 GET/POST

url: 請求地址

async:布爾類型,默認為true 表示請求是否為異步,如果為false表示為同步

dataType:返回的數據類型

jsonp:傳遞給請求處理程序或頁麵的,用以獲得jsonp回調函數名的參數名(一般默認為:callback)

jsonpCallback:自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名,也可以寫"?",jQuery會自動為你處理數據

success:調用成功執行的函數

error:異常處理函數

jquery ajax jsonp跨域調用實例代碼

使用GET方式和POST方式都可以進行跨域調用客戶端代碼如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" >
<head runat="server">
<script src="jquery-1.7.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
    function aa() {
        $.ajax({
            url: "https://localhost:12079/WebForm2.aspx",
            data: "p1=1&p2=2&callback=?",
            type: "post",
            processData: false,//processData的默認值是true,用於對data參數進行序列化處理
            timeout: 15000,
            dataType: "jsonp",  // not "json" we'll parse
            jsonp: "jsonpcallback",
            success: function(result) {
            alert(result.value1);
            }
        });
    }
</script>
</head>
<body>
    <form  runat="server"><div></div></form>
    <p><input  type="button" value="button"  /></p>
</body>
</html>

客戶端使用jsonp來傳輸數據

@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } 
<script type="text/javascript"> 
functionSendData() 
{ 
$.ajax({ 
    type: "get", 
    async: false, 
    url: "/home/ReturnJson", 
    dataType: "jsonp", 
    jsonp: "callback",//傳遞給請求處理程序或頁麵的,用以獲得jsonp回調函數名的參數名(一般默認為:callback) 
    jsonpCallback: "receive",//自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名,也可以寫"?",jQuery會自動為你處理數據 
    success: function(data){ 
        alert(data.name); 
    }, 
    error: function(){ 
        alert('fail'); 
    } 
}); 
} 
functionreceive(data) { 
    alert(data.age); 
} 
</script> 
<input type="button" value="提交" /> 

點擊提交按鈕後,發現服務器端的Request.QueryString["callback"]返回一個隨機函數名。這樣就被設置成JSONP格式來傳遞數據了

最後更新:2017-05-22 15:02:56

  上一篇:go  通過 AWS 的 Lambda 和 API Gateway 走向 Serverless
  下一篇:go  17張思維導圖,一網打盡機器學習統計基礎(附下載)