最近在測如何用jQuery讀取其它網頁的資料顯示,在網路上找到一篇簡單利用jQuery取得yahoo RSS新聞的範例,在本機可以執行,但一上server後就出現了沒有使用權限的問題
先前大概瞭解Javascript因為安全性問題,所以無法進行cross-domain的讀取,所謂cross-domain就是跨網域讀資料簡單來說就是a.com的網頁程式要去取b.com網頁資料,不過在現在web 2.0的時代,常會有需要進行跨網域的讀取,所以一樣大致上網整理了一下,目前有的作法如下:
JSONP
jQuery的文件有提到,從1.2版本開始支援使用 jQuery.getJSON(url,[data],[callback])
來進行跨網域讀取資料,原文如下:
As of jQuery 1.2, you can load JSON data located on another domain if you
specify a JSONP
callback, which can be done like so: “myurl?callback=?”. jQuery automatically
replaces the ? with the correct method name to call, calling your specified
callback.
如果要懂JSONP是什麼,小弟先前有篇文章就有提到,在此不多說啦,JSONP其實就是運用json資料格式,及回呼程式(callback=?)的方式達到可以取得到其它網域的資料並且執行後續callback的function,現在目前很多open API 例如yahoo,google, flickr 等都有支援callback的方式。
不過一般要使用JSONP,就是要你Client及Server之間的偶合度要高,除了其它有提供支援的網站可以使用外,所以適用度是有點限制的,不過還是要介紹一下,如何運作,在國王的新衣: JSONP 這篇網誌有提供取得flickr的圖片,小弟稍做修改成jQuery的寫法:
Client端:
$(function() {
$('#button1').click(function(){
var strURL='http://api.flickr.com/services/feeds/photos_public.gne?tags=羅平,油菜花,sunset&tagmode=all&format=json&jsoncallback=doPhoto';
$.ajax({
type:'GET',
dataType:'jsonp',
url:strURL,
error: function(xmlHttpRequest,error) {
alert('Ajax request ERROR');
}
})
})
});
function doPhoto(result) {
var div = document.getElementById(“flickr”);
for(var i=0; i < result.items.length; i++) {
var img = document.createElement(“img”);
img.setAttribute(“src”,result.items[i].media.m);
img.setAttribute(“alt”,result.items[i].title);
var a = document.createElement(“a”);
a.setAttribute(“href”,result.items[i].link);
a.setAttribute(“target”,”_blank”);
a.appendChild(img);
div.appendChild(a);
}
}
<input name=”button1″ id=”button1″ type=”button” value=”test” />
<div id=”flickr”></div>
Server端:
doPhoto({
“title”: “每個人的相片 已標籤 羅平, 油菜花 和 sunset”,
“link”: “http://www.flickr.com/photos/”,
“description”: “”,
“modified”: “2007-04-22T14:19:09Z”,
“generator”: “http://www.flickr.com/”,
“items”: [
{
“title”: “羅平金雞嶺夕陽”,
“link”: “http://www.flickr.com/photos/38362352@N00/468370409/”,
“media”: {“m”:”http://farm1.static.flickr.com/211/468370409_319f383a24_m.jpg”},
“date_taken”: “2007-04-22T22:19:09-08:00”,
“description”: “…”,
“published”: “2007-04-22T14:19:09Z”,
“author”: “nobody@flickr.com (Nature RGB)”,
“author_id”: “38362352@N00”,
“tags”: “sunset yunnan 油菜花 羅平”
}
]
})
當Server端回傳json格式的資料時,會依callback傳的doPhoto回傳,剛好client我們有個doPhoto function去執行接收到json的資料,大致就是這樣,而http://a.webvm.net/也有一個很簡單的範例,是呼叫另一個domain的json格式的 hello world 。
跨域代理(Cross Domain
Proxy)
主要原理就是用php或者其他語言寫一個代理請求的轉發過程。客戶端請求自己的服務器,服務器把請求轉發到目標地址並且得到回應,服務器再
把結果返回給客戶端。這個過程,對於開發者來說還是不錯的選擇,因為你可以在服務器上對回應的結果做自己的處理,可以決定需不需把結果要返回給客戶端。 不過還是一樣,需要有伺服端的配合,不過至少不用限制說一定要被請求端回傳json格式的資料才行,而這個proxy寫起來不然但小心有心人士利用,所以還是要判斷一下是不是由你認定的客戶端下的請求或是限定只proxy哪些網址。
而參考範例,以參考 Javascript 抓取跨網域外的資料 Tsung's Blog 的文章,但也是調整一下來看:
Client端:
$(function() {
$('#button1').click(function(){
$.ajax({
type:'Post',
dataType:'html',
data: {
strURL:'http://tw.yahoo.com/'
},
url: “proxy.jsp”,
error: function(xmlHttpRequest,error) {
alert('Ajax request ERROR');
},
success:function(html){
$(“#flickr”).html(html);
}
})
})
});
<input name=”button1″ id=”button1″ type=”button” value=”test” />
<div id=”flickr”></div>
Server端:
<?php
if (isset($_POST['url']) && !empty($_POST['url']))
{
// 記得檢查此 URL 是不是你發出的 request
echo
file_get_contents($_POST['url']);
}
?>
參考資料:
http://www.dotblogs.com.tw/topcat/archive/2008/08/08/4846.aspx
http://blog.zol.com.cn/859/article_858048.html
http://plog.longwin.com.tw/programming/2008/12/15/javascript-ajax-get-cross-domain-data-2008
http://carffuca.javaeye.com/blog/65239
http://happytemplate.blogspot.com/2007/11/jsonp.html
http://ibox.blog.sohu.com/107171814.html
http://www.javaeye.com/topic/169765
http://a.webvm.net/
近期留言