想象使用一個簡單HTML文件來把一個請求發送到一個服務器端腳本收到一個基於該請求的定制XML文件然後把它顯示給用戶而幾乎不需要刷新浏覽器!本文作者將同你一起探討怎樣在普通Web應用程序中聯合PHP和AJAX技術來創建實時的數據傳輸而不需要進行浏覽器刷新
盡管本文所使用的是PHP語言但是請記住任何服務器端語言都會正常工作為了理解本文我假定你基本理解JavaScript和PHP或一類似服務器端語言
本文示例使用AJAX來把一請求從一個RSS饋送發送到一定制的PHP對象該PHP對象復制一份在本地服務器上的該饋送並返回這一路徑該請求對象收到這一路徑分析它並且把數據以HTML形式顯示給用戶這聽起來涉及很多步驟其實它僅由個小文件組成之所以使用了個小文件是為了平衡它們各自特定的力量而使整個系統的處理極富效率性
有些讀者可能會問為什麼你要創建在本地服務器上的饋送的一個副本而不是簡單分析最原始的饋送原因是這樣以來可以允許繞過XML HTTP Request對象所強加的跨域限制後面我還會解釋怎樣創建這個定制的PHP對象但是首先讓我們從表單創建開始
創建發出請求的表單
你要做的第一事情是在你的HTML的head標簽之間包括你可能想使用的JavaScript和任何CSS文件我包括了一個式樣表來實現該聚合器的最後布局並用一個JavaScript文件來發出請求和進行饋送分析
<link href=css/layoutcss rel=stylesheet type=text/css />
<script src=js/requestjs></script>
下一步創建一個表單它針對你所選擇的一個RSS饋送發出請求我創建的表單只包括一個輸入字段和一個提交該請求的按鈕該請求的查詢是一個字符串它由饋送輸入值和一個將在服務器端被校驗的口令字組成作為一個示例我使用了下面形式
password=mypassword
該代碼在每次頁面加載之時發出一次請求因此如果頁面被刷新現有的在該輸入域中的饋送串將在頁面加載時被請求下面是一個表單數據的示例連同一些div標簽用來顯示已分析的饋送的特定結點
<body onload=javascript:makeRequest(requestphp?request= + documentfeedFormfeedvalue + password=mypassword);>
<form name=feedForm method=post action=javascript:makeRequest(requestphp?request= + documentfeedFormfeedvalue + password=mypassword);>
Enter a feed: <input type=text name=feed id=feed size=>
<input type=submit name=submit value=Add Feed>
</form>
<div id=logo></div>
<hr/>
<div id=copy></div>
<div id=details></div>
</body>
我所創建的這三個div標簽是logocopy和details其中每一個都在布局樣式表中有一個與之相關聯的樣式當我們分析饋送時將會用到它們但是我們首先需要能夠存取我們所請求的饋送這可以使用我前面所提到的PHP對象來完成
創建定制的PHP對象
我用PHP創建了一個小型RSS類它在本地服務器上創建一個請求饋送的副本這樣它可以為我們稍後要創建的XML HTTP Request對象所存取典型地你不能跨域請求一個文件這意味著你要請求的文件需要位於本地服務器上這個類是一種解決跨域問題的辦法因為它創建該饋送的一個副本這個副本在本地服務器上被請求並且把本地路徑返回到該饋送然後它由該Request對象來存取
這個類中唯一的方法是一個請求方法它僅有一個指向所請求的RSS 饋送的URL的參數然後它通過rss的名字來檢查是否一目錄位於本地服務器上如果不存在就創建一個並把其權限模式設置為這意味著該目錄可讀寫當被設置為可讀的時該目錄就可以在以後被存取而當被設置為可寫的時就可以把該饋送的一個副本寫向本地服務器上的目錄
//如果不存在目錄就創建一個
$dir = rss;
if(!is_dir($dir))
{
mkdir($dir );
}
注意
在一台Windows機器上對於PHP 及以上版本中模式設置是不被要求的但是如果它存在的話它將被忽略因此我保留了它以備該工程被遷移到一台UNIX或Linux服務器上
在把饋送復制到該服務器前我們需要一個唯一的文件名我對這個完整的URL使用了md加密方法以確保所有饋送的名字是唯一的通過這個新的文件名它可以連接一個描述指向該文件的目錄的字符串這將在創建該饋送的副本時使用
//創建唯一的命名
$file=md($rss_url);
$path=$dir/$filexml;
通過使用被定義在上面的路徑和到原始的被請求的饋送的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 );
}
// 創建一個唯一的名字
$file = md($rss_url);
$path = $dir/$filexml;
//復制饋送到本地服務器
copy($rss_url $path);
return $path;
}
}
}
?>
為了存取該PHP類中的方法需要有一個請求文件來擔當到該類的一個接口這也正是我們正在請求的文件這個文件首先驗證從該請求查詢的一口令變量或者返回一條指定該請求者不是一名經授權的用戶的消息或者用指向RSS饋送(該饋送在由請求方法處理後被復制到本地服務器)的路徑作出響應為了響應該RSS饋送需要包含這個RSS對象並把它實例化並且需要通過使用被請求的饋送的URL作為一參數來激活請求方法:
<?
if($password == mypassword)
{
require_once(classes/RSSclassphp);
$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){
postonreadystatechange = sendRequest;
postopen(POST url true);
postsend(url);
}
一旦收到來自於PHP對象的響應並被正確加載則對與該響應相應的本地文件發出另一個請求在這種情況中postresponseText提供給我們該新文件的路徑
function sendRequest(){
if(checkReadyState(post)){
request = createRequestObject();
requestonreadystatechange = onResponse;
requestopen(GET postresponseText true);
requestsend(null);
}
}
分析響應
由於RSS饋送之間的區別分析響應具有一定的挑戰性一些含有包含標題和描述結點的圖像而其它則沒有因此當我們分析回饋時我們需要做一點檢查來譯解它是否包括一圖像如果它包括一圖像我們就可以與該饋送的標題和鏈接一起在image div標簽中顯示該圖像
var _logo = ;
var _title = responsegetElementsByTagName(title)[]firstChilddata;
var _link = responsegetElementsByTagName(link)[]firstChilddata;;
_logo += <a href= + _link + target=_blank> + _title + </a><br/>;
if(checkForTag(responsegetElementsByTagName(image)[]))
{
var _url = responsegetElementsByTagName(url)[]firstChilddata;
_logo += <img src= + _url + border=><br/>
}
documentgetElementById(logo)innerHTML = _logo;
我們不僅必須檢查每個圖像以顯示它當遍歷饋送中所有的項時我們還需要對之進行檢查因為如果存在一個圖像那麼所有另外的標題和鏈接結點索引都將無法正常工作因此當發現圖像標簽時我們應該通過在每一次遍歷中增加索引值(+)來調整標題和鏈接結點的索引
if(checkForTag(responsegetElementsByTagName(image)[]) i>){
var _title=responsegetElementsByTagName(title)[i+]firstChilddata;
var _link=responsegetElementsByTagName(link)[i+]firstChilddata;
}
else{
var _title =responsegetElementsByTagName(title)[i]firstChilddata;
var _link = responsegetElementsByTagName(link)[i]firstChilddata;
}
你可以使用checkForTag方法來檢查是否存在特定的標簽
function checkForTag(tag){
if(tag != undefined) {
return true;
}
else{
return false;
}
}
存在許多種進行饋送分析的可能性例如你可以把項賦到類別上並使得該類別可折迭這樣用戶就可以對其想觀看的內容進行選擇作為一個示例我使用日期來對項進行分類這可以通過譯解是否針對一個特定項的pubDate不同於前一個項的pubDate並且相應地顯示一新的日期來實現
if(i>){
var previousPubDate = responsegetElementsByTagName(pubDate)[i ]firstChilddata;
}
if(pubDate != previousPubDate || previousPubDate == undefined){
_copy += <div id=detail> + pubDate + </div><hr align=left width=%/>;
}
_copy += <a href=\javascript:showDetails( + i + );\> + _title + </a><br/><br/>;
documentgetElementById(copy)innerHTML += _copy;
注意上面的最後一部分是showDetails方法它用於當一用戶從一個饋送中選擇一特定的項時進行細節顯示這個方法有一個參數(項索引值)這個索引用於發現在該饋送中details結點的索引
function showDetails(index){
documentgetElementById(details)innerHTML = responsegetElementsByTagName(description)[index]firstChilddata;
}
結論
使用AJAX發送查詢字符串到一個服務器端腳本並檢索一個基於該串的定制響應這對於任何web開發者都有實現的可能這樣以來你的下一個web應用程序也將會充滿了新的可能性
From:http://tw.wingwit.com/Article/program/PHP/201311/21366.html