AJAX的跨域與JSONP(為文章自動添加短址的功能)

來源:互聯網
上載者:User

什麼是AJAX的跨域請求
出於安全的考慮,如果你要從www.a.com通過Ajax來請求另外一個網站www.b.com的內容,瀏覽器是不允許你這樣做的(不理解這裡的安全是指什嗎?想想如果沒有這個限制的話,駭客可以做些什麼)。那什麼樣的情況下算是跨域?網域名稱不同那當然算是跨域了,例如a.com向b.com發送請求,這當然就是跨域了,不允許的。不過子網域名稱不同(例如sub.a.com向www.a.com發送請求)甚至是同網域名稱不同連接埠(例如a.com:80向a.com:8080)也算是跨域的。
下面示範一個跨域的例子: 複製代碼 代碼如下:<script type="text/javascript" >
//jQuery代碼
$("#btnCrossDomainRequest").click(function(){
$.get('http://www.jb51.net', function(data){
alert('success');
});
});
</script>

(在IE8下提示沒有許可權,在FF3.5.5和Google瀏覽器下都沒有提示,汗~我記得FF以前的版本是有提示的。。IE6下應該會彈窗提示(沒記錯的話))
跨域AJAX請求的解決方案
在AJAX應用環境中,由於安全的原因,瀏覽器不允許XMLHttpRequest組件請求跨域資源。在很多情況下,這個限制給我來帶來的諸多不便。很多同行,研究了各種各樣的解決方案:
1. 通過修改document.domain和隱藏的IFrame來實現跨域請求。這種方案可能是最簡單的一種跨域請求的方案,但是它同樣是一種限制最大的方案。首先,它只能實現在同一個頂級網域名稱下的跨域請求;另外,當在一個頁面中還包含有其它的IFrame時,可能還會產生安全性異常,拒絕訪問。
2.通過請求當前域的代理,由伺服器代理去訪問另一個域的資源。XMLHttpRequest通過請求本域內的一個伺服器資源,將要訪問的目標資源提供給伺服器,交由伺服器去代理訪問目標資源。這種方案,可以實現完全的跨域訪問,但是開發,請求過程的消費會比較大。
3. 通過HTML中可以請求跨域資源的標籤引用來達到目的,比如Image,Script,LINK這些標籤。在這些標籤中,Script無疑是最合適的。在請求每一個指令碼資源時,瀏覽器都會去解析並運行指令檔內定義的函數,或需要馬上執行的JavaScript代碼,我們可以通過伺服器返回一段指令碼或 JSON對象,在瀏覽器解析執行,從而達到跨域請求的目的。使用script標籤來實現跨域請求,只能使用get方法請求伺服器資源。

第一個解決方案需要根網域名稱是相同的,例如 a.domain.com和 b.domain.com。整個解決方案大概如所示:

第二個解決方案就是在伺服器端通過WebClient(或者其他)的類來請求跨域的內容,這裡需要注意的一點是,如果你要將cookies資訊也包含在WebClient的請求中的話,你需要手動的去將Cookies資訊加到WebClient中去。

第三個解決方案就和我們下面需要說道的JSONP有關的。

JSONP
JSONP全稱應該是“JSON with padding”吧,它正是利用了<script />可以跨域請求的特性。簡單來說JSONP就是在用戶端將要用來處理請求結果的函數名作為參數傳遞給伺服器端,然伺服器端將請求結果資料作為參數封裝在這個函數中並返回給用戶端執行。有點抽象?那麼直接看圖吧:

下面來個執行個體講解一下。這個執行個體就是為我們的博文自動產生一個短址的url,為了牆內的朋友方便,我們就直接使用國內的http://s8.hk提供的短址服務(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>

測試下,什嗎?不可以?肯定不可以啦,因為是跨域嘛,所以我們需要利用<script />標籤可以跨域請求的特性: 複製代碼 代碼如下:<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;
//注意下面將函數名‘alertShortUrl'傳進去咯
c_url += '&jsonp=alertShortUrl'
//產生一個<script />標籤並添加到<head />中
script = $('<script type="text/javascript" />')
.attr('src', c_url);
//這裡為什麼要用appendChild?
//因為jQuery的append方法對<script/>已經做了處理
//你也可以用$('head').append(script);
//這裡不用只是為了讓你看得更清楚點而已。
$('head')[0].appendChild(script[0]);
});
</script>

哈哈,再點點測試按鈕看看?很好,成功了。
其實不用這麼麻煩,因為jQuery自從1.2版以後就已經添加了對JSONP的支援,你只需要給一個問號作為預留位置就可以了,所以我們上面的代碼可以寫成: 複製代碼 代碼如下:<script type="text/javascript">
$("#shortItByjQueryJSONP").click(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面只需一個問號,不用具體的函數名
c_url += '&jsonp=?'
//注意是getJSON 哦
$.getJSON(c_url, function(data){
alert(data);
});
});
</script>

哈哈,是不是很簡便呢?下面就用這個實現為我們的文章添加自動縮短網址的功能吧: 複製代碼 代碼如下:<script type="text/javascript">
$(function(){
c_url = 'http://s8.hk:8088/s8/s?format=text&longUrl=';
c_url += document.location.href;
//注意下面只需一個問號,不用具體的函數名
c_url += '&jsonp=?'
$.getJSON(c_url, function(data){
//這裡要這麼處理、放到哪裡就看你自己喜歡咯.而且這還和你部落格使用的模板有關的哦
$("<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等國外的短址服務,牆得厲害,每次看不到很鬱悶。盡量不要用那些牆得厲害的吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.