AJAX的跨域與JSONP(為文章自動添加短址的功能)
更新時(shí)間:2010年01月17日 03:22:41 作者:
AJAX的跨域與JSONP(另送一個(gè)為文章自動添加短址的功能)
什么是AJAX的跨域請求
出于安全的考慮,如果你要從www.a.com通過Ajax來請求另外一個(gè)網(wǎng)站www.b.com的內(nèi)容,瀏覽器是不允許你這樣做的(不理解這里的安全是指什么?想想如果沒有這個(gè)限制的話,黑客可以做些什么)。那什么樣的情況下算是跨域?域名不同那當(dāng)然算是跨域了,例如a.com向b.com發(fā)送請求,這當(dāng)然就是跨域了,不允許的。不過子域名不同(例如sub.a.com向www.a.com發(fā)送請求)甚至是同域名不同端口(例如a.com:80向a.com:8080)也算是跨域的。
下面演示一個(gè)跨域的例子:
<script type="text/javascript" >
//jQuery代碼
$("#btnCrossDomainRequest").click(function(){
$.get('http://www.dbjr.com.cn', function(data){
alert('success');
});
});
</script>
(在IE8下提示沒有權(quán)限,在FF3.5.5和Google瀏覽器下都沒有提示,汗~我記得FF以前的版本是有提示的。。IE6下應(yīng)該會彈窗提示(沒記錯(cuò)的話))
跨域AJAX請求的解決方案
在AJAX應(yīng)用環(huán)境中,由于安全的原因,瀏覽器不允許XMLHttpRequest組件請求跨域資源。在很多情況下,這個(gè)限制給我來帶來的諸多不便。很多同行,研究了各種各樣的解決方案:
1. 通過修改document.domain和隱藏的IFrame來實(shí)現(xiàn)跨域請求。這種方案可能是最簡單的一種跨域請求的方案,但是它同樣是一種限制最大的方案。首先,它只能實(shí)現(xiàn)在同一個(gè)頂級域名下的跨域請求;另外,當(dāng)在一個(gè)頁面中還包含有其它的IFrame時(shí),可能還會產(chǎn)生安全性異常,拒絕訪問。
2.通過請求當(dāng)前域的代理,由服務(wù)器代理去訪問另一個(gè)域的資源。XMLHttpRequest通過請求本域內(nèi)的一個(gè)服務(wù)器資源,將要訪問的目標(biāo)資源提供給服務(wù)器,交由服務(wù)器去代理訪問目標(biāo)資源。這種方案,可以實(shí)現(xiàn)完全的跨域訪問,但是開發(fā),請求過程的消費(fèi)會比較大。
3. 通過HTML中可以請求跨域資源的標(biāo)簽引用來達(dá)到目的,比如Image,Script,LINK這些標(biāo)簽。在這些標(biāo)簽中,Script無疑是最合適的。在請求每一個(gè)腳本資源時(shí),瀏覽器都會去解析并運(yùn)行腳本文件內(nèi)定義的函數(shù),或需要馬上執(zhí)行的JavaScript代碼,我們可以通過服務(wù)器返回一段腳本或 JSON對象,在瀏覽器解析執(zhí)行,從而達(dá)到跨域請求的目的。使用script標(biāo)簽來實(shí)現(xiàn)跨域請求,只能使用get方法請求服務(wù)器資源。
第一個(gè)解決方案需要根域名是相同的,例如 a.domain.com和 b.domain.com。整個(gè)解決方案大概如下圖所示:
第二個(gè)解決方案就是在服務(wù)器端通過WebClient(或者其他)的類來請求跨域的內(nèi)容,這里需要注意的一點(diǎn)是,如果你要將cookies信息也包含在WebClient的請求中的話,你需要手動的去將Cookies信息加到WebClient中去。
第三個(gè)解決方案就和我們下面需要說道的JSONP有關(guān)的。
JSONP
JSONP全稱應(yīng)該是“JSON with padding”吧,它正是利用了<script />可以跨域請求的特性。簡單來說JSONP就是在客戶端將要用來處理請求結(jié)果的函數(shù)名作為參數(shù)傳遞給服務(wù)器端,然服務(wù)器端將請求結(jié)果數(shù)據(jù)作為參數(shù)包裝在這個(gè)函數(shù)中并返回給客戶端執(zhí)行。有點(diǎn)抽象?那么直接看圖吧:
下面來個(gè)實(shí)例講解一下。這個(gè)實(shí)例就是為我們的博文自動生成一個(gè)短址的url,為了墻內(nèi)的朋友方便,我們就直接使用國內(nèi)的http://s8.hk提供的短址服務(wù)(API地址)。
我們試下
<script type="text/javascript">
$("#shortIt").click(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
$.get(c_url,function(data){
alert(data);
})
});
</script>
測試下,什么?不可以?肯定不可以啦,因?yàn)槭强缬蚵?,所以我們需要利?lt;script />標(biāo)簽可以跨域請求的特性:
<script type="text/javascript">
function alertShortUrl(url){
alert(url);
}
$("#shortItByJSONP").click(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面將函數(shù)名‘a(chǎn)lertShortUrl'傳進(jìn)去咯
c_url += '&jsonp=alertShortUrl'
//生成一個(gè)<script />標(biāo)簽并添加到<head />中
script = $('<script type="text/javascript" />')
.attr('src', c_url);
//這里為什么要用appendChild?
//因?yàn)閖Query的append方法對<script/>已經(jīng)做了處理
//你也可以用$('head').append(script);
//這里不用只是為了讓你看得更清楚點(diǎn)而已。
$('head')[0].appendChild(script[0]);
});
</script>
哈哈,再點(diǎn)點(diǎn)測試按鈕看看?很好,成功了。
其實(shí)不用這么麻煩,因?yàn)閖Query自從1.2版以后就已經(jīng)添加了對JSONP的支持,你只需要給一個(gè)問號作為占位符就可以了,所以我們上面的代碼可以寫成:
<script type="text/javascript">
$("#shortItByjQueryJSONP").click(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面只需一個(gè)問號,不用具體的函數(shù)名
c_url += '&jsonp=?'
//注意是getJSON 哦
$.getJSON(c_url, function(data){
alert(data);
});
});
</script>
哈哈,是不是很簡便呢?下面就用這個(gè)實(shí)現(xiàn)為我們的文章添加自動縮短網(wǎng)址的功能吧:
<script type="text/javascript">
$(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面只需一個(gè)問號,不用具體的函數(shù)名
c_url += '&jsonp=?'
$.getJSON(c_url, function(data){
//這里要這么處理、放到哪里就看你自己喜歡咯.而且這還和你博客使用的模板有關(guān)的哦
$("<div>本文短址:</div>").css("font-weight", "normal")
.css("font-size", "12px")
.append($("<a>"+data+"</a>").attr("href", data))
.appendTo(".post .postTitle");
});
});
</script>
OK,打完收工。Enjoy it!
再多說幾句,在twitter上很多還是用bit.ly、j.mp等國外的短址服務(wù),墻得厲害,每次看不到很郁悶。盡量不要用那些墻得厲害的吧。
出于安全的考慮,如果你要從www.a.com通過Ajax來請求另外一個(gè)網(wǎng)站www.b.com的內(nèi)容,瀏覽器是不允許你這樣做的(不理解這里的安全是指什么?想想如果沒有這個(gè)限制的話,黑客可以做些什么)。那什么樣的情況下算是跨域?域名不同那當(dāng)然算是跨域了,例如a.com向b.com發(fā)送請求,這當(dāng)然就是跨域了,不允許的。不過子域名不同(例如sub.a.com向www.a.com發(fā)送請求)甚至是同域名不同端口(例如a.com:80向a.com:8080)也算是跨域的。
下面演示一個(gè)跨域的例子:
復(fù)制代碼 代碼如下:
<script type="text/javascript" >
//jQuery代碼
$("#btnCrossDomainRequest").click(function(){
$.get('http://www.dbjr.com.cn', function(data){
alert('success');
});
});
</script>
(在IE8下提示沒有權(quán)限,在FF3.5.5和Google瀏覽器下都沒有提示,汗~我記得FF以前的版本是有提示的。。IE6下應(yīng)該會彈窗提示(沒記錯(cuò)的話))
跨域AJAX請求的解決方案
在AJAX應(yīng)用環(huán)境中,由于安全的原因,瀏覽器不允許XMLHttpRequest組件請求跨域資源。在很多情況下,這個(gè)限制給我來帶來的諸多不便。很多同行,研究了各種各樣的解決方案:
1. 通過修改document.domain和隱藏的IFrame來實(shí)現(xiàn)跨域請求。這種方案可能是最簡單的一種跨域請求的方案,但是它同樣是一種限制最大的方案。首先,它只能實(shí)現(xiàn)在同一個(gè)頂級域名下的跨域請求;另外,當(dāng)在一個(gè)頁面中還包含有其它的IFrame時(shí),可能還會產(chǎn)生安全性異常,拒絕訪問。
2.通過請求當(dāng)前域的代理,由服務(wù)器代理去訪問另一個(gè)域的資源。XMLHttpRequest通過請求本域內(nèi)的一個(gè)服務(wù)器資源,將要訪問的目標(biāo)資源提供給服務(wù)器,交由服務(wù)器去代理訪問目標(biāo)資源。這種方案,可以實(shí)現(xiàn)完全的跨域訪問,但是開發(fā),請求過程的消費(fèi)會比較大。
3. 通過HTML中可以請求跨域資源的標(biāo)簽引用來達(dá)到目的,比如Image,Script,LINK這些標(biāo)簽。在這些標(biāo)簽中,Script無疑是最合適的。在請求每一個(gè)腳本資源時(shí),瀏覽器都會去解析并運(yùn)行腳本文件內(nèi)定義的函數(shù),或需要馬上執(zhí)行的JavaScript代碼,我們可以通過服務(wù)器返回一段腳本或 JSON對象,在瀏覽器解析執(zhí)行,從而達(dá)到跨域請求的目的。使用script標(biāo)簽來實(shí)現(xiàn)跨域請求,只能使用get方法請求服務(wù)器資源。
第一個(gè)解決方案需要根域名是相同的,例如 a.domain.com和 b.domain.com。整個(gè)解決方案大概如下圖所示:
第二個(gè)解決方案就是在服務(wù)器端通過WebClient(或者其他)的類來請求跨域的內(nèi)容,這里需要注意的一點(diǎn)是,如果你要將cookies信息也包含在WebClient的請求中的話,你需要手動的去將Cookies信息加到WebClient中去。
第三個(gè)解決方案就和我們下面需要說道的JSONP有關(guān)的。
JSONP
JSONP全稱應(yīng)該是“JSON with padding”吧,它正是利用了<script />可以跨域請求的特性。簡單來說JSONP就是在客戶端將要用來處理請求結(jié)果的函數(shù)名作為參數(shù)傳遞給服務(wù)器端,然服務(wù)器端將請求結(jié)果數(shù)據(jù)作為參數(shù)包裝在這個(gè)函數(shù)中并返回給客戶端執(zhí)行。有點(diǎn)抽象?那么直接看圖吧:
下面來個(gè)實(shí)例講解一下。這個(gè)實(shí)例就是為我們的博文自動生成一個(gè)短址的url,為了墻內(nèi)的朋友方便,我們就直接使用國內(nèi)的http://s8.hk提供的短址服務(wù)(API地址)。
我們試下
復(fù)制代碼 代碼如下:
<script type="text/javascript">
$("#shortIt").click(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
$.get(c_url,function(data){
alert(data);
})
});
</script>
測試下,什么?不可以?肯定不可以啦,因?yàn)槭强缬蚵?,所以我們需要利?lt;script />標(biāo)簽可以跨域請求的特性:
復(fù)制代碼 代碼如下:
<script type="text/javascript">
function alertShortUrl(url){
alert(url);
}
$("#shortItByJSONP").click(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面將函數(shù)名‘a(chǎn)lertShortUrl'傳進(jìn)去咯
c_url += '&jsonp=alertShortUrl'
//生成一個(gè)<script />標(biāo)簽并添加到<head />中
script = $('<script type="text/javascript" />')
.attr('src', c_url);
//這里為什么要用appendChild?
//因?yàn)閖Query的append方法對<script/>已經(jīng)做了處理
//你也可以用$('head').append(script);
//這里不用只是為了讓你看得更清楚點(diǎn)而已。
$('head')[0].appendChild(script[0]);
});
</script>
哈哈,再點(diǎn)點(diǎn)測試按鈕看看?很好,成功了。
其實(shí)不用這么麻煩,因?yàn)閖Query自從1.2版以后就已經(jīng)添加了對JSONP的支持,你只需要給一個(gè)問號作為占位符就可以了,所以我們上面的代碼可以寫成:
復(fù)制代碼 代碼如下:
<script type="text/javascript">
$("#shortItByjQueryJSONP").click(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面只需一個(gè)問號,不用具體的函數(shù)名
c_url += '&jsonp=?'
//注意是getJSON 哦
$.getJSON(c_url, function(data){
alert(data);
});
});
</script>
哈哈,是不是很簡便呢?下面就用這個(gè)實(shí)現(xiàn)為我們的文章添加自動縮短網(wǎng)址的功能吧:
復(fù)制代碼 代碼如下:
<script type="text/javascript">
$(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面只需一個(gè)問號,不用具體的函數(shù)名
c_url += '&jsonp=?'
$.getJSON(c_url, function(data){
//這里要這么處理、放到哪里就看你自己喜歡咯.而且這還和你博客使用的模板有關(guān)的哦
$("<div>本文短址:</div>").css("font-weight", "normal")
.css("font-size", "12px")
.append($("<a>"+data+"</a>").attr("href", data))
.appendTo(".post .postTitle");
});
});
</script>
OK,打完收工。Enjoy it!
再多說幾句,在twitter上很多還是用bit.ly、j.mp等國外的短址服務(wù),墻得厲害,每次看不到很郁悶。盡量不要用那些墻得厲害的吧。
您可能感興趣的文章:
- 跨域請求之jQuery的ajax jsonp的使用解惑
- jquery ajax jsonp跨域調(diào)用實(shí)例代碼
- AJAX實(shí)現(xiàn)跨域的三種方法(代理,JSONP,XHR2)
- AJax與Jsonp跨域訪問問題小結(jié)
- JSONP跨域GET請求解決Ajax跨域訪問問題
- 通過jsonp獲取json數(shù)據(jù)實(shí)現(xiàn)AJAX跨域請求
- AJAX跨域請求之JSONP獲取JSON數(shù)據(jù)
- 淺談JQuery+ajax+jsonp 跨域訪問
- Ajax jsonp跨域請求實(shí)現(xiàn)方法
- ajax和jsonp跨域的原理本質(zhì)詳解
相關(guān)文章
基于jquery的劃詞搜索實(shí)現(xiàn)(備忘)
最近,需要做個(gè)劃詞搜索功能。在網(wǎng)上找了好些,最后,參照進(jìn)行修改,實(shí)現(xiàn)了想要的功能。這里,做個(gè)記錄,以備日后所用。2010-09-09
jQuery實(shí)現(xiàn)頁面滾動時(shí)智能浮動定位
本文主要介紹了jQuery實(shí)現(xiàn)頁面滾動時(shí)智能浮動定位的方法。附上完整代碼,具有一定的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01
jquery 實(shí)現(xiàn)的改變顏色與背景的代碼 change(fontsize,background)補(bǔ)充2
change事件會在元素失去焦點(diǎn)的時(shí)候觸發(fā),也會當(dāng)其值在獲得焦點(diǎn)后改變時(shí)觸發(fā)。2010-05-05
jQuery實(shí)現(xiàn)的支持IE的html滑動條
本文給大家分享的是一段使用jQuery實(shí)現(xiàn)支持IE的html滑動條代碼,效果非常不錯(cuò),這里推薦給大家,希望大家能夠喜歡。2015-03-03
jQuery插件實(shí)現(xiàn)控制網(wǎng)頁元素動態(tài)居中顯示
這篇文章主要介紹了jQuery插件實(shí)現(xiàn)控制網(wǎng)頁元素動態(tài)居中顯示,實(shí)例分析了jQuery插件的實(shí)現(xiàn)與元素動態(tài)顯示的技巧,需要的朋友可以參考下2015-03-03
jquery實(shí)現(xiàn)超簡單的瀑布流布局【推薦】
本文主要介紹了jquery實(shí)現(xiàn)超簡單的瀑布流布局的實(shí)例,代碼簡單,容易修改。下面跟著小編一起來看下吧2017-03-03
IE10中flexigrid無法顯示數(shù)據(jù)的解決方法
這篇文章主要介紹了IE10中flexigrid無法顯示數(shù)據(jù)的解決方法的相關(guān)資料,需要的朋友可以參考下2015-07-07

