1. 程式人生 > >網站建設之項目實戰

網站建設之項目實戰

xmlhttp plm sof 代碼 utili 正在執行 郵件客戶端 kit thead

下載書籍 [download PDF]

在大型項目中使用 PHP 和 MySQL

  • 在 Web 開發中應用軟件工程
  • 規劃和運行 Web 應用程序項目
  • 重用代碼
  • 編寫可維護代碼
  • 實現版本控制
  • 選擇一個開發環境
  • 項目的文檔化
  • 建立原型
  • 分離邏輯、內容和外觀:PHP、HTML和CSS
  • 優化代碼

在 Web 開發中應用軟件工程

我們都知道,軟件工程是軟件開發過程中系統化的、可以量化的開發方法。也就是說,它是工程原則在軟件開發中的應用。

規劃和運行 Web 應用程序項目

基本步驟:

  • 明確目標用戶
  • 明確應用程序分成幾個部分,它們之間相互協調
  • 查看哪些功能模塊已經存在,不要重復造輪子
  • 明確工作進程,其包括
    • 代碼編寫標準
    • 目錄結構
    • 版本控制管理
    • 開發環境
    • 文檔化級別和標準
    • 小組成員的任務分配
  • 構建一個原型,展示給用戶,並反復修改和展示
  • 內容和邏輯分離
  • 系統優化
  • 邊開發邊測試

重用代碼

開發之前要看看哪些組件和函數可以從別的地方獲取。不要重復造輪子。

PHP 的一個優點是它有大量的內置的函數庫。查找函數的一個好方法是按照函數組分類的手冊。

應當避免多種編程語言參雜,有些程序員編寫的封裝函數用的是別的語言,這樣,程序的可維護性會降低,而且程序的執行效率也會降低。

如果發現所需的功能在PHP主函數庫裏沒有提供,那麽有兩個選擇。如果需要的功能非常簡單,可以選擇自己編寫該函數或對象。然而,如果需要創建一個相當復雜的功能——例如購物車、Web郵件系統或Web論壇——我們會發現這些東西別人已經做好了。在開放源代碼社區工作的一個動力就是像這些應用程序組件的代碼經常是免費的。如果發現某個組件與需要構建的相似甚至相同,那麽就可將這些源代碼作為基礎,在此基礎上修改或創建自己的組件。

編寫可維護代碼

  • 編碼標準

大多數IT組織都制定了編碼標準——選擇文件名、變量名以形成內部編碼準則、註釋代碼的準則、代碼縮進的準則等。

  • 對代碼的註釋

文件,無論是完整的腳本還是包含文件——每個文件應該有一個註釋,說明該文件的名稱、功能、作者和更新日期。

函數——函數的註釋應指明函數的功能,輸入參數和返回值。

類——註釋應描述類的用途。類方法應該具有與函數描述相同的註釋。

腳本或函數裏面的一大段代碼——在腳本之前添加一段偽碼樣式的註釋然後再編寫代碼是很好的。因此,初始化腳本可能是這樣:

<?php

    // validate input data

    // send to database

    // report results

?>

復雜的代碼——當整天圍繞某件事,或者花費了很長時間來解決這個問題時,應該編寫一段註釋解釋那樣做的原因。這樣,當下次看到這段代碼時,就不會皺著眉頭想,“究竟我為什麽會那樣做呢?”

  • 代碼縮進

縮進深度要明顯,但是不能太大。應當避免使用 TAB 鍵,雖然方便,但是占用太多空間,而且不同的編輯器 TAB 鍵縮進不同。一般縮進 2~3 個空格。

  • 分解代碼

將功能相似函數放到一個文件中,例如,可以將所有與數據庫相關的函數放到一個名為 dbfunctions.php 文件中。易讀,提高源代碼的重用性,方便維護和團隊工作。

  • 使用標準的目錄結構
  • 文檔化和共享內部函數

實現版本控制

  • BitKeeper
  • PERFORCE
  • GitHub

選擇一個開發環境

項目的文檔化

  • 設計文檔
  • 技術文檔/開發指南
  • 數據詞典(包含類文檔)
  • 用戶指南(盡管大多數 Web 應用程序是自我解釋的)

自動生成文檔:

  • phpdoc
  • phpDocumentor

建立原型

一個原型是對於獲得用戶需求很有意義的工具。通常,原型是應用程序的簡化的一部分工作版本,可以用來與客戶進行討論,並作為最終系統的基礎。對原型的多次反復討論將最終產生應用程序。

將邏輯和內容分離

基本方法:

  • 用包含文件保存不同部分的內容
  • 用一個函數或者帶有一組成員函數的類 API 將動態內容插入到靜態網頁模版中。
  • 使用模板系統。常用 Smarty

優化代碼

優化數據庫,減少用戶等待時間:

  • 減少數據庫連接。通常,這是最慢的部分
  • 加速數據庫查詢。通常的原則是盡可能減少連接,增加索引。
  • 使 PHP 中生成的靜態內容減少到最少。
  • 盡可能使用字符串函數代替正則表達式

使用 Zend 產品:http://www.zend.com

測試

  • 代碼審查。另一位編程人員來檢查
    • 可能忽略的錯誤
    • 原程序設計者沒有想到的測試用例
    • 代碼優化
    • 安全性的提高
    • 可以使用已有組件改進某一段代碼
    • 附加功能
  • 讓最終用戶作為測試人員

調試

  • 編程語法,運行時以及邏輯錯誤
  • 出錯信息
  • 錯誤級別
  • 出發自定義錯誤
  • 巧妙地處理錯誤

編程錯誤

錯誤類型:

  1. 語法錯誤
  2. 運行時錯誤
  3. 邏輯錯誤

使用變量幫助調試

下面的程序將打印出頁面包含的變量,有助於調試。

<?php

//these lines format the output as HTML comments
//and call dump_array repeatedly
echo"\n<!--BEGIN VARIABLE DUMP-->\n\n";
echo"<!--BEGIN GET VARS-->\n";
echo"<!--".dump_array($_GET)."-->\n";
echo"<!--BEGIN POST VARS-->\n";
echo"<!--".dump_array($_POST)."-->\n";
echo"<!--BEGIN SESSION VARS-->\n";
echo"<!--".dump_array($_SESSION)."-->\n";
echo"<!--BEGIN COOKIE VARS-->\n";
echo"<!--".dump_array($_COOKIE)."-->\n";
echo"\n<!--END VARIABLE DUMP-->\n";

//dump_array() takes one array as a parameter
//It iterates through that array,creating a single
//line string to represent the array as a set
function dump_array($array){
    if(is_array($array)){
    $size=count($array);
        $string="";
    if($size){
      $count=0;
      $string.="{";

      //add each element‘s key and value to the string
      foreach($array as$var=>$value){
        $string.=$var."=".$value;
        if($count++<($size-1)){
          $string.=",";
        }
      }
      $string.="}";
    }
    return $string;
    }
  else{
    //if it is not an array,just return it
    return $array;
  }
}
?>

錯誤報告級別

設置錯誤報告顯示級別:error_reporting()

改變錯誤報告設置

默認情況下,要改變所有腳本的錯誤報告,可以修改 php.ini 文件裏面的下面 4 行。

error_reporting=E_ALL&~E_NOTICE ;報告處通知外的所有錯誤
display_errors=On ;將錯誤顯示到屏幕
log_errors=Off ;不將錯誤寫入日誌
track_errors=Off ;不跟蹤錯誤

觸發自定義錯誤

使用函數:trigger_error()

巧妙地處理錯誤

錯誤處理函數:set_error_handler()

詳細可見:set_error_handler

示例程序在上面的鏈接中可見。

建立用戶身份驗證機制和個性化設置

  • 用戶登錄和驗證用戶
  • 管理密碼
  • 記錄用戶的個人喜好
  • 個性化內容
  • 基於已有的用戶信息為用戶推薦他們可能感興趣的內容

解決方案的組成

需求:

  • 識別每個用戶
  • 保存單個用戶的書簽
  • 根據對用戶的了解,向用戶建議他們可能感興趣的站點

用戶識別和個性化設置

將登錄名和密碼保存在一個 MySQL 數據庫中。

用戶以用戶名和密碼登錄,需要如下組件:

  • 註冊用戶名和密碼,需要限制其長度
  • 註冊過程中,用戶可見他們提供的詳細信息
  • 能夠退出
  • 網站能夠檢測用戶是否登錄
  • 用戶可以修改密碼,且不需要開發者幫助

以上的這些函數大多是可以重用的,或者從其他的項目中拿過來,稍加修改就可以重用。

保存書簽

需要實現的功能:

  • 用戶能夠取回,瀏覽書簽
  • 增加新書簽,檢查URL是否有效
  • 刪除書簽

推薦書簽

尋找相似用戶,提供保存的書簽

解決方案概述

在紙上繪制草圖,提出系統流程圖

技術分享圖片

建立函數庫,其作用如下:

  • 用戶身份驗證
  • 書簽保存與檢索
  • 數據驗證
  • 數據庫連接
  • 輸出到瀏覽器

具體實現

  • 代碼可以在這裏找到

文件說明:

文件名 描述
bookmarks.sql 創建數據庫的SQL語句
login.php 包含系統登錄表單的頁面
register_form.php 系統中用戶註冊表單
register_new.php 處理新註冊信息的腳本
forgot_form.php 用戶忘記密碼後需要填寫的表單
forgot_passwd.php 重新設置遺忘密碼的腳本
member.php 用戶的主頁面,包含該用戶所有的當前書簽
add_bm_form.php 添加書簽的表單
add_bms.php 將書簽真正添加到數據庫中的腳本
delete_bms.php 從用戶的書簽列表中刪除選定書簽的腳本
recommend.php 基於用戶以前的操作,推薦用戶可能感興趣的書簽
change_passwd_form.php 用戶修改密碼時要填的表單
change_passwd.php 修改數據庫中用戶密碼的表單
logout.php 將用戶註銷的腳本
bookmark_fns.php 應用程序包含的文件集合
data_valid_fns.php 確認用戶輸入數據有效的函數
db_fns.php 連接數據庫的函數
user_auth_fns.php 用戶身份驗證的函數
url_fns.php 增加和刪除書簽的函數
output_fns.php 以HTML形式格式化輸出的函數

創建一個購物車

功能:

  • 在線出售商品的數據庫
  • 一個在線產品目錄,按商品種類分類
  • 一個能記錄用戶打算購買商品的購物車
  • 結賬腳本,處理付款和運送細節
  • 一個管理界面

實例:在線書店

解決方案的組成

需求:

  • 我們需要找到一種將數據庫連接到用戶的瀏覽器的方法。用戶能夠按目錄瀏覽商品。
  • 用戶應該能夠從商品目錄中選取商品以便此後購買。我們也要能夠記錄他們選中的物品。
  • 當用戶完成購買,要合計他們的訂單,獲取運送商品細節,並處理付款。
  • 我們還應該為Book-O-Rama網站創建一個管理界面,以便管理員在上面添加、編輯圖書和目錄。

創建一個在線目錄

需要註意:

  • 完成訂單時,需要使用事務
  • 要使用事務,需要將表格轉換為 InnoDB 存儲引擎

在用戶購買商品時記錄購買行為

方法:

  • 將用戶的選擇存入數據庫
  • 使用會話變量

使用會話的好處是不用頻繁的查詢數據庫,而且也避免了在結束的時候留下許多垃圾數據,這適用於那些只是瀏覽或不停地改變主意的用戶。

因此,我們需要設計一個或一組會話變量來保存用戶的選擇。當用戶完成購買並付款之後,將此信息送到數據庫作為一個事務處理的記錄。

我們還可以使用該數據給出一個當前購物車的摘要描述,將其顯示在頁面的某個位置,以便用戶在任何時候都知道花費是多少。

實現一個付款系統

系統將數據發送給銀行,並返回成功代碼或者任何一個錯誤代碼類型。

需要記錄的信息:客戶的信息 -> 商業賬戶信息 -> 交易總金額

可以通過一個用戶的購物車會話變量計算出訂單的總量。將訂單的最終信息記錄到數據庫,並在此時銷毀會話變量。

創建一個管理界面

功能:添加、刪除和編輯數據庫中的圖書及目錄

需要保存商品購買時的價格,而不是當前價格。

解決方案概述

用戶視圖:

技術分享圖片

管理員視圖:

技術分享圖片

提示 該應用程序的代碼量非常大。其中要實現的許多功能我們都已經見過(特別是在上一章中),例如,將數據保存到數據庫,從數據庫中取回數據,授予用戶管理權限。在這方面的代碼,我們只簡要地看一下,而將大部分時間花在購物車函數上。

具體實現

  • 代碼可以在這裏找到

文件說明:

名稱 模塊 描述
index.php 目錄 網站首頁,顯示系統中的圖書目錄
show_cat.php 目錄 顯示特定目錄包含的所有圖書
show_book.php 目錄 顯示特定圖書的詳細信息
show_cart.php 購物車 顯示用戶購物車的內容,也用來向購物車中添加圖書
checkout.php 購物車 向用戶顯示所有的訂單細節,獲取運送細節
purchase.php 購物車 從用戶獲取付款細節
process.php 購物車 處理付款細節,將訂單添加到數據庫
login.php 管理 允許管理員登錄進行修改
logout.php 管理 管理員退出
admin.php 管理 主菜單菜單
change_password_form.php 管理 允許管理員修改密碼的表單
change_password.php 管理 修改管理員密碼
insert_category_form.php 管理 允許管理員向數據庫中添加一個目錄的表格
insert_category.php 管理 向數據庫中插入新目錄
insert_book_form.php 管理 管理員添加新書到系統的表單
insert_book.php 管理 將新書插入到數據庫
edit_category_form.php 管理 管理員編輯目錄的表單
edit_category.php 管理 更新數據庫中的目錄
edit_book_form.php 管理 管理員編輯圖書信息的表單
edit_book.php 管理 更新數據庫中的圖書信息
delete_category.php 管理 從數據庫中刪除一個目錄
delete_book.php 管理 從數據庫中刪除一本書
book_ac_fns.php 函數 該應用程序的包含文件集合
admin_fns.php 函數 管理腳本使用的函數集合
book_fns.php 函數 用以保存和獲取圖書數據的函數集合
order_fns.php 函數 用以保存和獲取訂單數據的函數集合
output_fns.php 函數 輸出HTML的函數集合
data_valid_fns.php 函數 驗證用戶輸入數據的函數集合
db_fns.php 函數 連接book_ac數據庫的函數集合
user_auth_fns.php 函數 授權管理員用戶的函數集合
book_sc.sql SQL 創建book_ac數據庫的SQL
populate.sql SQL 插入樣本數據到book_ac數據庫中的SQL

創建一個基於 Web 的電子郵件服務系統

在這個項目中,我們將建立一個電子郵件客戶端,Warm Mail,它允許用戶:

  • 連接到 POP3 或 IMAP 郵件服務器上的賬戶
  • 閱讀郵件
  • 發送郵件
  • 恢復郵件信息
  • 轉發郵件消息
  • 從用戶賬戶中刪除郵件

解決方案的組成

接收和處理郵件的協議:POP3 和 IMAP。

其中:(通常情況下)

  • POP3 :從服務器下載或刪除郵件而短時間連接網絡
  • IMAP :可以使用戶與郵件進行交互,而且郵件可以永久保存在遠程服務器上

發送郵件的的協議:SMTP

使用函數mail()

雖然PHP對IMAP和POP3有著不錯的支持,但它都是通過IMAP函數庫所提供的功能來實現的。為了使用本章所提供的代碼,需要安裝IMAP庫。可以通過查看phpinfo()函數的輸出來判斷是否已經安裝該庫。

即將使用的 IMAP 函數:

  • imap_open()
  • imap_close()
  • imap_headers()
  • imap_header()
  • imap_fetchheader()
  • imap_body()
  • imap_delete()
  • imap_expunge()

解決方案概述

功能展示:

技術分享圖片

具體實現

  • 代碼可以在這裏找到

文件說明:

文件名 類型 描述
index.php 應用程序 運行整個應用程序的主要腳本
include_fns.php 函數 該應用程序包含文件的集合
data_valid_fns.php 函數 使輸入數據生效的函數集合
db_fns.php 函數 連接到mail數據庫的函數集合
mail_fns.php 函數 打開郵箱、閱讀郵件與郵件相關的函數集合
output_fns.php 函數 輸出HTML函數的集合
user_auth_fns.php 函數 驗證用戶函數的集合
create_database.sql SQL 用來建立book_sc數據庫和建立用戶的SQL

創建一個郵件列表管理器

項目源代碼 [link]

下載書籍 [download]查看本章完整講解

創建一個 Web 論壇

項目源代碼 [link]

下載書籍 [download]查看本章完整講解

生成 PDF 格式的個性化文檔

下載書籍 [download]查看本章完整講解

使用 XML 和 SOAP 來連接 Web 服務

  • 理解 XML 和 Web 服務的基本知識
  • 使用 XML 與 Amazon 進行交互
  • 使用 PHP 的 SimpleXML 庫解析 XML
  • 緩存響應
  • 使用 NuSOAP 與 Amazon 進行交互

項目概述:使用 XML 和 Web 服務

目標:

  1. 理解什麽是 XML 和 SOAP 並且掌握如何在 PHP 中使用它們
  2. 使用這兩種技術與外界進行通信

與其他站點進行交互的兩種方式:

  1. 使用基於 HTTP 的 XML,也就是表示狀態轉換(REST)
  2. 使用 SOAP

理解 XML

XML 和 HTML 的不同:

  • 在 XML 中,所有開始的標記都必須有一個對應的結束標記。這條規則的例外是空元素。
  • XML 可以在文檔中設置自己的標記
  • 可以通過編寫一個 DTD(文檔類型定義)或XML 模式來規範化 XML 文檔結構。可以將 DTD 或模式看作是一個類聲明,而 XML 文檔則是類的實例。

理解 Web 服務

Web 服務是通過 Internet 可供使用的應用程序接口。我們可以將 Web 服務看作是一個通過 Web 開放了其公有方法的類。

在這種遠程函數調用方法中,還涉及了一些核心協議。最重要的兩個協議是 SOAP 和 WSDL。

  1. SOAP

SOAP 是一個以請求和響應為驅動的消息傳遞協議,它允許客戶端調用 Web 服務,服務器對客戶端的調用進行響應。

每一個 SOAP 消息,無論是請求的還是響應的,都是一個簡單的 XML 文檔。

  1. WSDL

WSDL 是 Web 服務描述性語言的縮寫(發音:wiz-dul)。這個協議是用來描述特定 Web 站點上可供使用的接口的。

解決方案的組成

實例要求:在自己的站點上顯示 Amazon 的商品信息,然後讓用戶在本站下單,訂單的處理由 Amazon 完成。

我門只需要提供一個基本的購物車,這樣就可以記錄客戶想要購買哪些產品,並且在用戶結賬時將這些產品報告給 Amazon。

使用 Amazon 的 Web 服務接口

參考文檔:https://forums.aws.amazon.com/index.jspa

在註冊開發人員令牌時,需要註意協議的幾個條件:

  • 作為客戶端,每秒鐘不能發出多個請求
  • 必須緩存來自 Amazon 的數據
  • 可以 24 小時緩存大多數數據,而一些穩定屬性可以緩存至 3 個月
  • 如果緩存價格或庫存信息超過 1 個小時,必須提供一些聲明
  • 必須將本地所擁有的所有 Amazon 數據鏈接到 Amazon 站點的頁面,嚴禁將從 Amazon 下載的文本或圖形鏈接至其他商業網站

XML 的解析:REST 響應

Amazon為其Web服務提供的第一個最受歡迎的接口是通過REST實現的。這個接口可以接受一個普通的HTTP請求並且返回一個XML文檔。要使用這個接口,需要解析Amazon返回給我們的XML響應。可以通過PHP的SimpleXML庫來實現XML的解析。

在 PHP 中使用 SOAP

另一種可以提供相同Web服務的接口是SOAP。要使用SOAP訪問這些服務,我們需要使用許多不同的PHP SOAP庫中的其中之一。PHP內置有SOAP庫,但是由於該庫並不是一直可用的,因此可以使用NuSOAP庫。由於NuSOAP是用PHP編寫的,它並不需要進行編譯。它只是一個可以通過require_once()進行調用的文件。

下載 NuSOAP

NuSOAP 的 GitHub 源代碼

緩存

正如我們前面提到的,亞馬遜對開發人員提出的條件和約束之一就是必須緩存通過Web服務下載的數據。在我們的解決方案中,仍然需要找到一個保存和重復使用所下載數據的方法,當然必須在這些數據失效之前。

解決方案概述

本項目只是幾個簡單的購物車頁面,所以沒有結構圖。

具體實現

  • 代碼可以在這裏找到

文件說明:

文件名稱 類型 描述
index.php 應用程序 主要應用程序文件
about.php 應用程序 顯示“關於”頁面
constants.php 包含文件 設置一些全局變量
topbar.php 包含文件 生成每一個頁面和CSS之間的信息欄
bottom.php 包含文件 生成每一個頁面的註腳
AmazonResultSet.php 類文件 包含保存每一個Amazon查詢結果的PHP類
Product.php 類文件 包含保存特定圖書信息的PHP類
bookdisplayfunctions.php 函數 包含用來顯示圖書信息和圖書列表的函數
cachefunctions.php 函數 包含執行Amazon所需的緩存操作相關的函數
cartfunctions.php 函數 包含與購物車相關的函數
categoryfunctions.php 函數 包含用來檢索和顯示一個目錄的函數
utilityfunctions.php 函數 包含在整個應用程序中要使用到的工具函數的集合

安裝項目代碼

步驟:

  • 創建一個緩存目錄
  • 設置這個緩存目錄的讀寫權限,這樣腳本就可以對其進行寫操作
  • 編輯constants.php代碼,使其提供緩存的位置
  • 註冊一個Amazon開發人員令牌
  • 編輯constants.php代碼,使其包括開發人員令牌,此外,還可以選擇是否包括會員ID
  • 確認已經安裝了NuSOAP。我們將其安裝在Tahuayo目錄下,但是也可以將其安裝在不同位置,並對其進行修改
  • 檢查PHP5是否在帶有XML支持的條件下進行編譯的

擴展這個項目

參考Amazon的Web服務資源中心提供的應用。

進一步學習

  • http://www.w3.org/XML/Core/
  • web服務:http://www.w3.org/2002/ws/

使用 Ajax 構建 Web 2.0 應用

  • 整合腳本和置標語言創建 Ajax 應用
  • 一個 Ajax 應用的基本組成部分,包括發送請求以及解析來自服務器的響應
  • 如何修改前面章節介紹應用的元素來創建支持 Ajax 的頁面
  • 代碼庫以及如何需求幫助信息

Ajax 是什麽

通常,Ajax 編程是將處理 XML 格式數據傳輸的客戶端 JavaScript 編程與某種服務器端編程語言(eg:PHP)的結合。此外,XHTML 和 CSS 也被用來展示支持 Ajax 的元素。

典型的,Ajax 編程的結果是為一個交互式應用提供更加清晰和快捷的用戶接口——例如,連接到 Facebook,Flicker 以及其他社交網站的接口。

  • HTTP請求和響應

  • DHTML 和 XHTML

    DHTML 也叫 HTML。當使用 JavaScript 請求頁面的時候,所有的數據都是從服務上獲取的。如果使用 Ajax ,只有預留區域會從服務器中獲取,而其他部分保持不變。

    XHTML :可擴展的超文本置標語言。通過設備(Web 瀏覽器,手機等)來顯示標記的內容,並且支持集成 CSS 來提供顯示的額外控制。

    XHTML 和 HTML 的不同之處在於 XHTML 遵循 XML 的語法,以及除了標準的 Web 瀏覽工具外,XHTML 還可以被 XML 工具來解析。

    XHTML 的元素和屬性都是小寫字母,所有的元素必須顯式封閉。

  • CSS

  • 客戶端編程

    客戶端編程是指從 Web 服務器中獲取所有的程序函數,等待客戶端的調用。

    常用的客戶端編程語言是 JavaScript,也就是 Ajax 中的字母 “J”

  • 服務器端編程

    服務器端編程是指 Web 服務器給出響應之前做的處理腳本。

    服務器端語言可以是:Perl,JSP,ASP,PHP

  • XML 和 XSLT

    XML 就是 Ajax 中的字母 “x”,它主要用於交換數據;XSLT 用來操作數據。數據本身將通過所創建的 Ajax 應用發送或獲取。

Ajax 基礎

本節將使用 Ajax 的組成部分創建一個可用的示例程序。

請記住:使用 Ajax 的一個主要原因:創建一個能夠相應用戶動作的交互式網站,而這些響應並不需要刷新整個頁面。

要實現此功能,Ajax 應用需要包括一個能夠處理發生在所請求的 Web 頁面與負責生成該頁面的 Web 服務器之間額外層。這個額外層通常就是指 Ajax 框架(也就是 Ajax 引擎)。該框架用來處理終端用戶和 Web 服務器之間的請求,它可以不需要額外的動作就交流請求和響應,例如重新刷新頁面,或者中斷用戶正在執行的動作(例如,滾動、點擊或閱讀一段文本)。

XMLHTTPRequest對象

由於安全原因,該對象只能調用同一域的URL;不能直接調用遠程服務器。

XMLHTTPRequest對象也被看作是Ajax應用的“通道(guts)”,因為它是客戶端請求和服務器端響應的“通道”。雖然接下來將介紹創建和使用XMLHTTPRequest對象的基礎知識,請參閱https://www.w3.org/TR/XMLHttpRequest/獲取詳細信息。

創建對象的函數

function getXMLHTTPRequest() {
   var req =  false;
   try {
      /* for Firefox */
      req = new XMLHttpRequest(); 
   } catch (err) {
      try {
         /* for some versions of IE */
         req = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (err) {
         try {
            /* for some other versions of IE */
            req = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (err) {
            req = false;
         }
     }
   }
   
   return req;
}

與服務器通信

創建一個向服務器發送請求的函數:

function getServerTime() {
  var thePage = ‘servertime.php‘;
  myRand = parseInt(Math.random()*999999999999999); # 創建隨機數
  var theURL = thePage +"?rand="+myRand;
  myReq.open("GET", theURL, true);
  myReq.onreadystatechange = theHTTPResponse;
  myReq.send(null);
}

/* 處理服務器響應 */
function theHTTPResponse() {
  if (myReq.readyState == 4) {
    if(myReq.status == 200) {
       var timeString = myReq.responseXML.getElementsByTagName("timestring")[0];
       document.getElementById(‘showtime‘).innerHTML = timeString.childNodes[0].nodeValue;
    }
  } else {
    document.getElementById(‘showtime‘).innerHTML = ‘<img src="ajax-loader.gif"/>‘;
  }
}

頁面:

<?php
header(‘Content-Type: text/xml‘);
echo "<?xml version=\"1.0\" ?>
      <clock>
        <timestring>It is ".date(‘H:i:s‘)." on ".date(‘M d, Y‘).".</timestring>
      </clock>";
?>

處理服務器響應

解釋響應並向終端用戶顯示一個字符串

function theHTTPResponse() {
  if (myReq.readyState == 4) {
    if(myReq.status == 200) {
       var timeString = myReq.responseXML.getElementsByTagName("timestring")[0];
       document.getElementById(‘showtime‘).innerHTML = timeString.childNodes[0].nodeValue;
    }
  } else {
    document.getElementById(‘showtime‘).innerHTML = ‘<img src="ajax-loader.gif"/>‘;
  }
}

上面的源代碼可見[link]

整合應用

ajaxServerTime.html:包含樣式單以及能夠調用遠程PHP腳本並獲取服務器響應的JavaScript腳本

在以前的項目中添加Ajax元素

項目源代碼可見 [link]

修改27章源代碼如下:

  • output_fns.php 中的 do_html_header()函數指向新的樣式單和JavaScript函數庫的鏈接
  • output_fns.php 中的 display_add_bm_form()函數也做了修改,添加標簽後不用離開頁面。添加了對 getXMLHTTPRequest()函數的調用
  • addNewBookmark()函數:創建變量,向PHP腳本發送數據以及調用函數處理服務器端的響應。
  • url_fns.php 中的 add_bm() 函數:關於錯誤信息的處理改成if語句

進一步學習

進一步了解文檔對象模型(DOM)

  • W3C關於文檔對象模型的技術報告:http://www.w3.org/DOM/DOMTR

  • DOM腳本編程組織的主頁:http://domscripting.webstandards.org/
  • Mozilla項目關於DOM的開發人員文檔:http://developer.mozilla.org/en/docs/DOM(以及關於JavaScript文檔的鏈接:http://developer.mozilla.org/en/docs/JavaScript)

Ajax應用可用的JavaScript函數庫

盡力減少重復性工作

  • Prototype JavaScript框架可以簡化DOM對象的操作。在創建復雜的Ajax應用時,可以使用XMLHTTPRequest對象。更多信息,請參閱:http://www.prototypejs.org/。

  • Dojo是一個開放源代碼的工具包,它包含了許多基本的JavaScript函數,一個創建框架以及有效的打包並向終端用戶分發代碼的機制。更多信息,請參閱:http://dojotoolkit.org/。

  • MochiKit是一個輕量級的代碼庫,它包含了處理DOM以及格式化客戶端輸出的函數。MochiKit的口號有點“不友好”但是很真實:“MochiKit使得JavaScript不那麽糟糕”。MochiKit提供的函數和解決方案,可供開發人員使用的文檔以及使用MochiKit創建的示例項目都值得一看。更多信息,請參閱:http://mochikit.com/。

Ajax開發人員網站

  • Ajaxian是一個開發人員門戶網站,它為新的或者有經驗的開發人員提供了新聞、文章、教程以及示例代碼。更多信息,請參閱:http://ajaxian.com/。

  • Ajax Matters包含一些深度介紹Ajax開發的文章。更多信息,請參閱:http://www.ajaxmatters.com/。

  • Ajax Lines是另一個開發人員門戶網站,它提供了關於Ajax所有內容的新聞和文章。更多信息,請參閱:http://www.ajaxlines.com/。

網站建設之項目實戰