【轉】退而求其次的選擇1:使用IFrame發送請求《深入理解Ajax:基於JavaScript的RIA開發 》

IFrames爲異步調用提供了一個合適的 傳輸途徑,因爲它們可以在不使整個頁面重新裝載的基礎上載入新內容,而新的IFrame元素則可以通過JavaScript創建。IFrame最好的屬性 之一是表單可以將其作爲目標,從而只需重載IFrame而不用對整個頁面進行重載; 該方法可以通過POST類型請求將大量數據發送給服務器。

在使用IFrame作爲傳輸方法時,其中的 一個難點是載入的頁面必須是HTML格式的,並且在載入完成時,需要通過JavaScript的onload事件句柄來告訴其父文檔。這就使得基於 IFrames發出的所有請求所針對的頁面都必須是針對IFrame請求設計的(其代碼無法像在XMLHttpRequest方法中那樣獲取一個XML文 件)。

注意,使用IFrames還有許多其他限制:

·  只支持異步請求;

·  需要修改服務器端頁面;

·  會在瀏覽器的歷史中加上虛構的項;

·  在某些瀏覽器上,會使後退、前進按鈕的行爲變得不確定;

·  在不同瀏覽器中的實現有巨大的不同,特別是在老版本的瀏覽器中。

IFrame和 XMLHttpRequest相比也有一個優點,即可以用來完成文件上傳。由於瀏覽器的安全限制,只有諸如單擊表單的用戶操作可以與用戶機器上的文件交 互。可以僅對文件上傳使用目標爲一個IFrame的表單,它不涉及常規的表單POST操作和頁面重載週期。不過,這不是針對文件上傳使用IFrame,而 對其他Ajax請求則使用XMLHttpRequest的理由。除非發起的是遠程腳本風格的Ajax請求(這將在第3章中講述),對於IFrame的限 制,會使所有Ajax開發項目的工作量大大增加。

1  創建一個隱藏IFrame

爲了最大程度上與老版本瀏覽器兼容,可以在HTML中添加IFrame並將其大小設置爲0x0(不能僅是隱藏它,否則有些瀏覽器將不會載入它)。不過該方 法的靈活性並不好,因此應該動態地創建這個幀。並非所有老版本的瀏覽器都支持document.createElement方法,但不支持該方法的瀏覽器 通常也不具備在載入數據時所需的其他動態能力,因此對於它們最好是提供一個靜態HTML版本的頁面。在下面的例子中,使用innerHTML創建了這個 IFrame,因爲它比使用DOM方法更簡單。注意,這裏也使用了document.createElement方法,用來添加div元素:

2  創建一個表單

如果要發起GET請求,只需修改 IFrames中src屬性的值,但進行POST請求時則需要使用一個目標表單。GET方法並不是Ajax請求的良好解決方案,主要有兩個原因:它能夠發 送的數據是有限的(具體的數據量限制取決於瀏覽器),GET請求會被代理服務器緩存且/或預載入,因此決不要用它來執行諸如數據庫更新之類的操作。

在IFrame中使用一個表單是很簡單的。只要設置表單的target屬性即可,當提交該表單時,其結果就將在該IFrame中載入。以下例子創建了我們的表單,並將其target屬性設置爲在第2.5.1節中創建的IFrame:

3  從載入的內容向原始文檔發送數據

要知道IFrame的內容已經載入的唯一方 法是在內容頁上運行一些JavaScript代碼,以提示IFrame所嵌入的父頁面。完成該任務的最簡單方法是設置載入文檔的onload事件句柄。這 一限制意味着使用IFrame不能像使用XMLHttpRequest那樣載入任意的內容。不過,當某個頁面已被作爲Ajax網關時,該方法仍然是很有效 的。以下就是一個onload事件句柄的實例:

4  基於IFrame的Ajax完整實例

一個完整的基於IFrame的Ajax實例中的請求包含兩個部分內容。第一部分是客戶端代碼,用來創建IFrame和表單;第二部分是服務器端代碼,它負責準備數據,並通過父文檔的onload事件句柄將其發送回去。

本例的第1部分(程序清單2-5所示)是位 於一個簡單HTML文件中的JavaScript代碼。該頁面用於測試;回調函數只是在警告對話框中顯示出結果。該例子的第2部分(程序清單2-6所示) 是一個簡單的PHP腳本,它負責從POST請求中獲取數據,並將其回送給父文檔。爲實現一個實際有效的系統,可能需要在表單中添加一些其他變量,以告訴 PHP代碼如何處理上傳的數據,或者可以在腳本中直接加入業務邏輯,並對要實現的每個任務都設置一個不同的目標頁。

程序清單2-5  使用IFrame發送一個Ajax請求

程序清單2-5中包含3個函數:

·  createRemotingDiv  用來設置IFrame。

·  sendRequest  用來發起Ajax請求。

·  test  發起Ajax請求。test函數在頁面的HTML代碼中與一個鏈接綁定在一起。用戶點擊該鏈接,將啓動一個Ajax請求。

函數 createRemotingDiv中所包含的代碼在前面已經描述過了,它包括的代碼用來創建隱藏IFrame以及將向其提交信息的表 單。在表單創建完後,其目標將是新創建的IFrame,用表單提交代替當前頁面的重載。開發時,經常在調試過程中顯示IFrame,這是很有效的,因爲可 以看到調用的頁面所生成的輸出。要實現該目標,可以將第8行修改爲“width:200;height:200”。

函數sendRequest用來發起Ajax請求。其參數包括請求將發向的URL、發送給服務器的payload,以及請求完成時將執行的回調函數。該函數使用 createRemotingDiv來配置這一過程。然後sendRequest將更新IFrame表單的操作,把 payload值填充到表單中,使用IFrame提交該表單。當在IFrame中載入了新頁面時,新文檔將通過JavaScript的onload句柄調 用已傳給sendRequest方法的回調函數。這個處理POST表單的PHP頁面,以及創建onload句柄的JavaScript代碼如程序清單 2-6所示。

程序清單2-6  處理基於IFrame的Ajax請求的PHP服務器端頁面

在服務器端,該表單將被處理,並將以HTML頁面的形式創建輸出。添加新數據的最簡單方法是生成包含新數據的JavaScript。在這裏,我們只是通過 爲result變量賦值的方法,將數據回顯給客戶端。通常,在此會運行服務器端代碼,或者輸出一個字符(就像本例這樣),或者添加將在父文 檔中執行的新JavaScript代碼。父文檔的回調函數是在body標籤的onload事件句柄中定義的。

 

注意: 以上JS代碼在插入的時候可能自動添加了mce字樣,調試時請自行去除~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章