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