ajax跨域 不用jsonp,jQuery的ajax跨域 Jsonp原理

1、Jsonp

Jsonp(json with padding)是JSON的一種“使用模式”,可用於解決主流瀏覽器的跨域數據訪問的問題。

Jsonp是為了解決ajax跨域發送http請求出現的,利用Script標簽的特性跨域。瀏覽器由於安全考慮,在編寫ajax程序時,httprequest/xmlhttp都不能發送非本域的http請求,是被瀏覽器所禁止的。所以ajax本身是無法跨域的。

2、同源策略

www.a.com網頁的ajax獲取www.b.com接口的內容,由於您的網頁域名是www.a.com,而您發送的ajax請求的目標域卻是www.b.com。瀏覽器會阻止這一的請求,這就是所謂的同源策略。

同源是指:js腳本只能訪問或者請求相同協議,相同domain(網址/ip),相同端口的頁面。

我們知道,js腳本可以訪問所在頁面的所有元素。通過ajax技術,js也可以訪問同一協議,同一個domain(ip),同一端口的服務器上的其他頁面,請求到瀏覽器端之后,利用js就可以進行任意的訪問。但是對於協議不同, 或者domain不同或者端口不同的服務器上的頁面就無能為力了,完全不能進行請求。下面是例子:(http://localhost:57269/頁面)

varxmlhttp;if(window.XMLHttpRequest) {

xmlhttp= newXMLHttpRequest();

}else{

xmlhttp=ActionXObject("Microsoft.XMLHTTP");

}

xmlhttp.onreadystatechange= function() {if(xmlhttp.readyState== 4 &&xmlhttp.status== 200) {

console.log(xmlhttp.responseText);

}

}varurl= "http://localhost:51355/Common/Test";

xmlhttp.open("Get", url,true);

xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");

xmlhttp.send();

這里為了結果不受其他js庫的干擾,使用了原生的XMLHttpRequest來處理,結果如下:

e314ed52451ada8cc74b9193dac31247.png

我們看到57269端口的ajax請求無法訪問51355端口的頁面。原因是“同源策略禁止讀取“某某”的遠程資源”。因為同源策略,普通的ajax無法跨域請求,解決這種問題的方式就是Jsonp。

3、Jsonp跨域的原理

我們發現凡是擁有"src"這個屬性的標簽都擁有跨域的能力,在頁面上有三種資源是可以與頁面本身不同源的。它們是:js腳本,css樣式文件,圖片,如下所示,它們是可以鏈接訪問到不同源的資源的。

1)

2)

3)

而jsonp就是利用了標簽可以鏈接到不同源的js腳本,來到達跨域目的。當鏈接的資源到達瀏覽器時,瀏覽器會根據他們的類型來采取不同的處理方式,比如,如果是css文件,則會進行對頁面 repaint,如果是img 則會將圖片渲染出來,如果是script 腳本,則會進行執行,比如我們在頁面引入了jquery庫,為什么就可以使用 $了呢?就是因為jquery庫被瀏覽器執行之后,會給全局對象window增加一個屬性:$,所以我們才能使用 $來進行各種處理。(另外為什么要一般要加css放在頭部,而js腳本放在body尾部呢,就是為了減少repaint的次數,另外因為js引擎是單線程執行,如果將js腳本放在頭部,那么在js引擎在執行js代碼時,會造成頁面暫停。)

jQuery封裝的 josnp 用法:

//第一種方式getJSON callback=?,其中 ? 會自動替換為function(data)函數。

$.getJSON("http://localhost:51355/Common/Test?callback=?", function(data) {var obj = JSON.parse(data); //很多網上的例子都是可以直接.age這樣寫的,但是我測試的時候無法這么做,必須要轉一次josn,需要轉josn,未能清楚為何沒有自動為我轉成json格式。

alert(obj.age);

});//第二種方式ajax,設定請求方式為jsonp

$.ajax({

async:false,

url:"http://localhost:51355/Common/Test", //跨域的url

type: "GET",

dataType:'jsonp', //返回格式

jsonp: "callback", //指定回調函數

data: "", //參數

success: function(data) {var obj = JSON.parse(data); //很多網上的例子都是可以直接.age這樣寫的,但是我測試的時候無法這么做,必須要轉一次josn,需要轉josn,未能清楚為何沒有自動為我轉成json格式。

alert(obj.age);

}

});

//需要考證是否正確

//jsonp: "callback", // 指定回調函數,這里名字可以為其他任意你喜歡的,比如callback,不過必須與下一行的GET參數一致

//data: "name=jxq&email=feichexia@yahoo.com.cn&callback=?", // callback與上面的jsonp值一致

C# MVC代碼:

//方式一

publicActionResult Test()

{string callback = Request["callback"]; //jsonp1503629838983

string name = "mr.zhang";string age = "20";string response = "{\"name\":\"" + name + "\",\"age\":\"" + age + "\"}";

System.Web.Script.Serialization.JavaScriptSerializer jss= newSystem.Web.Script.Serialization.JavaScriptSerializer();string call = callback + "(" + jss.Serialize(response) + ")"; //jsonp1503629838983("{\"name\":\"mr.zhang\",\"age\":\"20\"}")

returnContent(call);

}//方式二

public voidTest()

{string callback = Request["callback"]; //jsonp1503629838983

string name = "mr.zhang";string age = "20";string response = "{\"name\":\"" + name + "\",\"age\":\"" + age + "\"}";

System.Web.Script.Serialization.JavaScriptSerializer jss= newSystem.Web.Script.Serialization.JavaScriptSerializer();string call = callback + "(" + jss.Serialize(response) + ")"; //jsonp1503629838983("{\"name\":\"mr.zhang\",\"age\":\"20\"}")

Response.Write(call);

Response.End();

}

下面是我理解的josnp的原理(個人觀點):

一個簡單的JSONP請求可以通過一下代碼實現:

var callbackName = 'callback';

window[callbackName]= function(data) {var obj = JSON.parse(data); //很多網上的例子都是可以直接.age這樣寫的,但是我測試的時候無法這么做,必須要轉一次josn,需要轉josn,未能清楚為何沒有自動為我轉成json格式。

alert(obj.age);

}var script = document.createElement('script');

script.src= 'http://localhost:51355/Common/Test?callback=' +callbackName;

document.body.appendChild(script);

大概可以看出來,是創建了一個標簽,然后把我想請求的地址賦值給src。這樣我是不是可以繼續精簡一下。

Html的head代碼:

functioncallback(data) {varobj=JSON.parse(data);//轉josnalert(obj.age);

}

4、總結

1、這是我認為的josnp代碼實現方式,應該是先創建了一個類似callback函數,然后創建一個的標簽,通過標簽中的src指定的js腳本到達瀏覽器會執行的特性,發起請求告訴服務端函數名叫callback。html會把返回的字符串當作javascript代碼來進行解析,然后返回的是一個函數包裹的josn數據callback(josn),即callback("{\"name\":\"mr.zhang\",\"age\":\"20\"}"),然后調動本地的callback函數輸出josn。

2、jQuery是將jsonp封裝成類似ajax的樣子,是自動生成回調函數並把數據取出來供success屬性方法來調用。

3、因為標簽的請求方式就是Get。所以Jsonp只能使用Get請求,即使jQuery方式的ajax里寫的是post方式,最后也是get方式請求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值