大的方向上說,從Picasa服務(wù)器上取數(shù)據(jù),有兩種方式,一種是使用Google已經(jīng)開放的各種語言的API,可以在頁面http://code.google.com/apis/picasaweb/developers_guide_protocol.html找到很多相關(guān)的信息。另一種方式便是使用最樸素的網(wǎng)絡(luò)請求方式來自己構(gòu)造請求并解析回傳的數(shù)據(jù)。
由于Picasa只提供了Java,.NET,Python和PHP的接口,而Gadget目前只能使用JavaScript,因此我們只能使用樸素方式。
繼續(xù)第三節(jié)的路子,仍然使用XmlHttpRequest向Picasa服務(wù)發(fā)起請求,也要處理好四部分信息。
請求發(fā)向哪個URL:為了獲取Picasa的相冊信息,要向http://picasaweb.google.com/data/feed/api/user/default發(fā)請求,這個URL其實可以有很多變化的地方。例如user/default這個地方是請求所附token所屬的用戶相冊信息,這里當(dāng)然可以明確的指定用戶名。”api”可以換成”base”,這個將影響回傳數(shù)據(jù)的格式,但Goolge推薦使用api而不是base。
請求的類型:我們是要索取數(shù)據(jù),因此這是一個查詢的動作,應(yīng)該使用GET。
請求頭:只需要把token放進去就好。這樣來放:
xhRequest.setRequestHeader('Authorization','GoogleLogin auth=' + token);
消息體:對于我們查詢相冊的請求,不需要任何的消息體。
具體的代碼都在Main.prototype.fetchAlbumsInfo()函數(shù)中,就像這樣:
Main.prototype.fetchAlbumsInfo=function() {
var url="http://picasaweb.google.com/data/feed/api/user/default";
var token=options.getValue("token");
xhRequest= createXhr();
xhRequest.open("GET", url, true);
xhRequest.setRequestHeader('Authorization','GoogleLogin auth=' + token);
xhRequest.send(null);
xhRequest.onreadystatechange =function(){
if (!xhRequest) {
return;
}
if (xhRequest.readyState != 4) {
return;
}
main.albums=parseAlbumFeed(xhRequest.responseText);
main.fetchAlbumThumbnail();
}
};
最后兩個函數(shù)是下一步要做的工作:解析回傳的相冊數(shù)據(jù),并下載每個相冊的縮略圖。
要想解析回傳數(shù)據(jù),首先得知道回傳的數(shù)據(jù)是什么。你可以把這些數(shù)據(jù)打印出來看看,應(yīng)該是類似下面的樣子:

怎么,看著有點眼熟?沒錯,這個回傳數(shù)據(jù)所使用的格式正是標(biāo)準(zhǔn)的Atom Feed(更多的描述可以參考W3C的標(biāo)準(zhǔn)和下面的鏈接:http://code.google.com/intl/zh-CN/apis/picasaweb/developers_guide_protocol.html)。
可以根據(jù)Atom Feed的格式來編寫我們解析回傳數(shù)據(jù)的函數(shù)parseAlbumFeed(),這個函數(shù)的作用是從回傳的xml數(shù)據(jù)中找出我們關(guān)心的幾樣?xùn)|西:該用戶目前擁有的所有的相冊信息,包括每個相冊的標(biāo)題,描述,訪問權(quán)限以及縮略圖的地址。找出這些信息以后,將會拼成一個包含相冊(Album)的數(shù)組作為函數(shù)返回值。
具體代碼如下:
function parseAlbumFeed(response) {
var doc = createDomDocument();
doc.loadXML(response);
//用戶已經(jīng)建立過的相冊集合,函數(shù)的返回值
var albums = [];
var entryElements = doc.getElementsByTagName('entry');
//具體處理每個Album的信息
for (var i = 0; i < entryElements.length; i++) {
var entry = entryElements[i];
var album=new Album();
//相冊標(biāo)題
album.title=entry.getElementsByTagName('title')[0].text;
//相冊描述
album.summary=entry.getElementsByTagName('summary')[0].text;
//相冊的訪問權(quán)限
album.access=entry.getElementsByTagName('gphoto:access')[0].text;
//相冊的縮略圖
var thumbnail=entry.getElementsByTagName('media:thumbnail')[0];
album.thumbnail=new Thumbnail(thumbnail.getAttribute('url'));
albums.push(album);
}
return albums;
};
這個函數(shù)中用到了一些我們還沒有新建的類,相冊(Album)以及縮略圖(Thumbnail)。這些類的聲明可以放在一個新的名為album.js的文件中,并在我們整個Gadget的main.xml文件中指名要導(dǎo)入它。因此main.xml的最后幾行應(yīng)該看上去是這個樣子:
<script src="album.js" />
<script src="main.js" />
</view>
而album.js的內(nèi)容大體如下:
function Album() {
this.title = "";
this.summary="";
this.access="";
this.thumbnail=#ff0000;
}
function Thumbnail(url) {
this.url = url;
this.width = 40;
this.height = 40;
this.src = undefined; // XML response stream
}
最后還要在main.js里面添加一個函數(shù)createDomDocument(),用來提供一個DOM對象供我們解析XML用。代碼如下:
function createDomDocument() {
var doc = new DOMDocument();
try {
doc.resolveExternals = false;
doc.validateOnParse = false;
doc.setProperty('ProhibitDTD', false);
} catch(e) {
debug.warning('Could not set MS specific properties.');
}
return doc;
}
下一節(jié)來說說怎么取得相冊的縮略圖并顯示在Gadget的界面中。