Jsonp跨域訪問原理分析


Jsonp是什么?
Jsonp實(shí)際上是一種跨域ajax發(fā)送http請(qǐng)求的方法,

它不是什么全新的技術(shù),而是巧妙的利用,

組合目前的技術(shù)而實(shí)現(xiàn)跨域通訊的方法。我們知道瀏覽器由于安全考慮,

在編寫ajax程序時(shí),httprequest/xmlhttp都不能發(fā)送非本域的http請(qǐng)求,

類似下面的代碼

<!--www.a.com/test.aspx頁面里的內(nèi)容 -->

<script>

 ajax.request("http://www.b.com/ajaxserver.aspx",function(){});

</script>

都不會(huì)得到你想要的結(jié)果,由于您的網(wǎng)頁域名是www.a.com,

而您發(fā)送的ajax請(qǐng)求的目標(biāo)域卻是www.b.com。

瀏覽器會(huì)阻止這一的請(qǐng)求,這就是所謂的同源策略。

而Jsonp就是解決這一問題的其中一種方式。

Jsonp原理分析
假如我們有一個(gè)網(wǎng)頁www.a.com/index.aspx 

其中一段代碼如下:

<scriptsrc="http://www.b.com/test.js"><script>


test.js里面的代碼:

alert("我是屬于域www.b.com的");


顯然這佯做毫無問題,我們打開www.a.com/index.aspx的時(shí)候,

會(huì)彈出一個(gè)框(我是屬于www.b.com的)。

現(xiàn)在我們將www.a.com/index.aspx里面的代碼改成這樣

<script>
function test(str){
    alert(str);
}
window.onload=function(){var script=document.createElement("script");
    script.src="http://www.b.com/test.js";
    document.getElementByTagName("head")[0].appendChild(script);
}
</script>

www.b.com/test.js里面的內(nèi)容改成:

test("我是www.b.com/test.js里面的參數(shù)哦");



如果不意外的話,瀏覽器加載完依然會(huì)彈出一個(gè)對(duì)話框(我是www.a.com里面的函數(shù))。

這2個(gè)例子清晰的表明,對(duì)于js腳本,

瀏覽器并沒有同源的限制,www.a.com能夠直接使用www.b.com的javascript資源,

并且支持我們通過編寫javascript腳本,動(dòng)態(tài)的創(chuàng)建script標(biāo)簽,動(dòng)態(tài)加載。

那么我們能否利用瀏覽器對(duì)于script沒有同源限制的這一特性,

來實(shí)現(xiàn)我們的跨域通信呢,答案是肯定的,

jsonp實(shí)質(zhì)上就是利用了這一點(diǎn)。

現(xiàn)在假設(shè)www.a.com/index.aspx 有個(gè)用戶登陸了,

我們需要在index.aspx頁面要將這一信息發(fā)送給www.b.com/login.aspx。index.aspx

我們可以編寫如下面的代碼

function callback(ret){
 alert(ret);
}
var script=document.createElement("script");
script.src="http://www.b.com/login.aspx" "?name=" youname "&pwd=" pwd "&call=callback";
document.getElementByTagName("head")[0].appendChild(script);


在www.b.com/login.aspx頁面編寫如下代碼

Response.Header.Append("Content-Type","application/javascript");
var name=Request.QueryString["name"];
var pwd=Request.QueryString["pwd"];
var call=Request.QueryString["call"]
if(SystemService.Login(name,pwd)){
  Response.Write(call "('login success!')");}else{Response.Write(call "('name or pwd error!')");
}
Response.End();



大家如果能看懂上面的代碼嗎? 對(duì), 這就是所謂的jsonp。

Jsonp的缺點(diǎn)


1,目標(biāo)域的服務(wù)器必須要如你所愿的輸出一些你想要的腳本才可以。

如上面www.b.com/login.aspx頁面輸出的callback ,想象一下,

假如www.b.com/login.aspx輸出的并非callback;

而是輸出alert("。。。。。),那會(huì)是一種什么情況....

說白了, 目標(biāo)域,如果不受你控制,又不支持這樣方式,

那么你是無法使用Jsonp這種方式的。


2,只能使用Get請(qǐng)求


原文鏈接:Jsonp跨域訪問原理分析