<link href="css/layout.css" rel="stylesheet" type="text/CSS" /> <script src="js/request.JS"></script>
下一步,創建一個表單,它針對你所選擇的一個RSS饋送發出請求。我創建的表單只包括一個輸入字段和一個提交該請求的按鈕。該請求的查詢是一個字符串,它由饋送輸入值和一個將在服務器端被校驗的口令字組成;作為一個示例,我使用了下面形式: "password=mypassWord 該代碼在每次頁面加載之時發出一次請求;因此,如果頁面被刷新,現有的在該輸入域中的饋送串將在頁面加載時被請求。下面是一個表單數據的示例,連同一些div標簽用來顯示已分析的饋送的特定結點:<body onload="Javascript:makeRequest('request.PHP?request=' + document.feedForm.feed.value + '"password=mypassWord');"> <form name="feedForm" method="post" action="Javascript:makeRequest('request.PHP?request=' + document.feedForm.feed.value + '"password=mypassWord');"> Enter a feed: <input type="text" name="feed" id="feed" size="20"> <input type="submit" name="submit" value="Add Feed"> </form> <div id="logo"></div> <hr/> <div id="copy"></div> <div id="details"></div> </body>
我所創建的這三個div標簽是logo,copy和details,其中每一個都在布局樣式表中有一個與之相關聯的樣式。當我們分析饋送時將會用到它們,但是我們首先需要能夠存取我們所請求的饋送。這可以使用我前面所提到的PHP對象來完成。 創建定制的PHP對象 我用PHP創建了一個小型RSS類,它在本地服務器上創建一個請求饋送的副本,這樣它可以為我們稍後要創建的XML HTTP Request對象所存取。典型地,你不能跨域請求一個文件,這意味著你要請求的文件需要位於本地服務器上。這個類是一種解決跨域問題的辦法,因為它創建該饋送的一個副本,這個副本在本地服務器上被請求並且把本地路徑返回到該饋送,然後它由該Request對象來存取。 這個類中唯一的方法是一個請求方法,它僅有一個指向所請求的RSS 饋送的URL的參數。然後,它通過rss的名字來檢查是否一目錄位於本地服務器上。如果不存在,就創建一個並把其權限模式設置為0666,這意味著該目錄可讀寫。當被設置為可讀的時,該目錄就可以在以後被存取;而當被設置為可寫的時,就可以把該饋送的一個副本寫向本地服務器上的目錄: //如果不存在目錄就創建一個$dir = "rss"; if(!is_dir($dir)) { mkdir($dir, 0666); }
注意:在一台Windows機器上,對於PHP 4.2.0及以上版本中模式設置是不被要求的。但是,如果它存在的話,它將被忽略;因此,我保留了它,以備該工程被遷移到一台UNIX或Linux服務器上。 在把饋送復制到該服務器前,我們需要一個唯一的文件名。我對這個完整的URL使用了md5加密方法以確保所有饋送的名字是唯一的。通過這個新的文件名,它可以連接一個描述指向該文件的目錄的字符串;這將在創建該饋送的副本時使用: //創建唯一的命名$file=md5($rss_url); $path="$dir/$file.XML";
通過使用被定義在上面的路徑和到原始的被請求的饋送的URL的參考,現在我們能創建該文件的一個副本。最後,把該路徑返回到該新文件,作為對該請求的響應: //復制饋送到本地服務器copy($rss_url,"$path"); return $path; Following is the small, yet powerful RSS class in its entirety: <?PHP class RSS { function get($rss_url) { if($rss_url != "") {
//如果不存在目錄就創建一個$dir = "rss"; if(!is_dir($dir)) { mkdir($dir, 0666); }
// 創建一個唯一的名字$file = md5($rss_url); $path = "$dir/$file.XML";
//復制饋送到本地服務器copy($rss_url, "$path"); return $path; } } } ?> 為了存取該PHP類中的方法,需要有一個請求文件來擔當到該類的一個接口,這也正是我們正在請求的文件。這個文件首先驗證從該請求查詢的一口令變量,或者返回一條指定該請求者不是一名經授權的用戶的消息,或者用指向RSS饋送(該饋送在由請求方法處理後被復制到本地服務器)的路徑作出響應。為了響應該RSS饋送,需要包含這個RSS對象並把它實例化,並且需要通過使用被請求的饋送的URL作為一參數來激活請求方法:
<? if($password == "mypassWord") { require_once('classes/RSS.class.PHP'); $rss = new RSS(); echo $rss->get($request); } else { echo "You are an unauthorized user"; } ?>
GET/POST與AJax相結合
為了POST請求,我們首先需要創建該請求對象。如果你沒有創建請求對象的經驗,那麼可以讀一下我的文章《How To Use AJax》或簡單地研究一下本文的示例源代碼。一旦創建該請求對象,就可以調用sendFeed方法並傳遞由表單所創建的URL:
function sendFeed(url){
post.onreadystatechange = sendRequest;
post.open("POST", url, true);
post.send(url);
}
一旦收到來自於PHP對象的響應並被正確加載,則對與該響應相應的本地文件發出另一個請求。在這種情況中,post.responseText提供給我們該新文件的路徑:
function sendRequest(){
if(checkReadyState(post)){
request = createRequestObject();
request.onreadystatechange = onResponse;
request.open("GET", post.responseText, true);
request.send(null);
}
}
分析響應
由於RSS饋送之間的區別,分析響應具有一定的挑戰性。一些含有包含標題和描述結點的圖像,而其它則沒有。因此,當我們分析回饋時,我們需要做一點檢查來譯解它是否包括一圖像。如果它包括一圖像,我們就可以,與該饋送的標題和鏈接一起,在image div標簽中顯示該圖像:
var _logo = "";
var _title = response.getElementsByTagName('title')[0].firstChild.data;
var _link = response.getElementsByTagName('link')[0].firstChild.data;;
_logo += "<a href='" + _link + "' target='_blank'>" + _title + "</a><br/>";
if(checkForTag(response.getElementsByTagName('image')[0]))
{
var _url = response.getElementsByTagName('url')[0].firstChild.data;
_logo += "<img src='" + _url + "' border='0'><br/>"
}
document.getElementById('logo').innerHtml = _logo;
我們不僅必須檢查每個圖像以顯示它,當遍歷饋送中所有的項時我們還需要對之進行檢查。因為如果存在一個圖像,那麼所有另外的標題和鏈接結點索引都將無法正常工作。因此,當發現圖像標簽時,我們應該通過在每一次遍歷中增加索引值(+1)來調整標題和鏈接結點的索引:
if(checkForTag(response.getElementsByTagName('image')[0]) "" i>0){
var _title=response.getElementsByTagName('title')[i+1].firstChild.data;
var _link=response.getElementsByTagName('link')[i+1].firstChild.data;
}
else{
var _title =response.getElementsByTagName('title')[i].firstChild.data;
var _link = response.getElementsByTagName('link')[i].firstChild.data;
}
你可以使用checkForTag方法來檢查是否存在特定的標簽:
function checkForTag(tag){
if(tag != undefined) {
return true;
}
else{
return false;
}
}
存在許多種進行饋送分析的可能性。例如,你可以把項賦到類別上並使得該類別可折迭,這樣用戶就可以對其想觀看的內容進行選擇。作為一個示例,我使用日期來對項進行分類-這可以通過譯解是否針對一個特定項的pubDate不同於前一個項的pubDate並且相應地顯示一新的日期來實現:
if(i>1){
var previousPubDate = response.getElementsByTagName('pubDate')[i-1].firstChild.data;
}
if(pubDate != previousPubDate || previousPubDate == undefined){
_copy += "<div id='detail'>" + pubDate + "</div><hr align='left' width='90%'/>";
}
_copy += "<a href="Javascript:showDetails('" + i + "');">" + _title + "</a><br/><br/>";
document.getElementById('copy').innerHtml += _copy;
注意,上面的最後一部分是showDetails方法,它用於當一用戶從一個饋送中選擇一特定的項時進行細節顯示。