就從 Remote Scripting 出發吧
首先以簡報常用的方式做個無聊的開場白: 從 Remote Scripting 出發, 何謂 Remote Scripting? 又要出發到哪? 廢話! 就是不知道才找你來講解, 你反問我們衝啥, 小朋友?
然而我得坦承: 事實上 Remote Scripting 並非我的出發點, 我是在找尋 iframe 相關文章時無意間翻到的. 雖然事後發現沿著 RS 會通往 AJAX, 也很高興早先便有人寫出類似的觀點. 但是我相信藉由創意, RS 的 ideas 能開出更多條路! 因此, 出發吧! 雖然不知會到哪, 探索未知的世界總是令人興奮莫名, 不是嗎?
縱使前途無量, 總不能漫無目標. 這裡我大略抓幾個 RS 的特色作為主軸: 1.溝通; 2.回應; 3.延伸.
RS 的起源據說是為了解決在不刷新當前頁面的情形和伺服器交流. 對此在下有點小小不認同: 從伺服器所的結果頁面內容必然和原先頁面不同, 至少時戳就會更新. 而 刷新 的行為較似 重置 回快取內的資料; 只有 重載 的作法才是原地直送原汁原味. 雖然龜毛, 但觀念釐清後對 location 物件的操作會更有感覺. 拉回 RS, 基本的想法便是在客戶面前安插一個公關經理: 對伺服器以專屬協定溝通後獲取資料暫存在公關部的辦公室; 對客戶則以各種 Script 方式動態改變當前頁面. 於是徵才廣告刊上了報, 一堆狠角色便前來報名, 大略有 : Java Applet, Flash, ActiveX Object, 甚至在本站通告不斷的 iFrame. 沒錯, 今天的節目中我們再度邀請了 iFrame 當特別來賓, 反正他的價錢低廉又耐操好用; 但在轉給他之前, 先把鏡頭帶到其他幾位來賓身上...
在 Sun 推出 Java 1.0 後, 各大網站紛紛加入 Applets 特效和聊天室好展現技術. 如今特效仍在資源網站和坊間個人網頁中沉睡著, 扮演溝通橋樑的聊天室早已撤的撤、荒的荒, 形同希臘的 月亮神殿, 卻連一隻螞蟻也沒有. 也許色情網站的視訊聊天還在用吧, 但要我架的話會採 Flash Communicator + Video 來實作. 因為 java.awt 實在太 ugly... heavy 了, 而為了 swing 要訪客們建立一個臃腫的 JRE 也實在強人所難. 恭喜微軟移除 JRE 的策略成功了, 現在 clients 只願意裝 cab 檔, 於是就連 Flash 也進化成 cab 迎合 <object> 語法. 總括而論, 藉由這些小元件, 就能搭起友誼的橋樑.
巧的是, 各大瀏覽器在下載資料時是採取 muliti-threads 方式運作的. 所以這些網頁間的小元件(在正常情況下)便能自個兒運行, 使用者不用苦苦等待伺服器回應一樣能瀏覽頁內其餘部份資訊. 這個特性有別於更改網址→送出要求→等待回應→畫面空白或鎖住→等等等等→載入內容, 稱之為 不同步, 就是 AJAX 的 A 特色.
現在, 把一個 name="robot" 的 frame 當成 DOM 架構中的一個元件, 所有和伺服器溝通的事就交給他吧. 於是更改 robot.location 便能達到向伺服器 request 的結果. 雖然這和單一頁面 request sever 沒啥不同, 不過現在只有 robot 在專心等待, 並不影響其他 frame 的瀏覽或操作. 這樣不正也恰好是所謂的 不同步 了嗎?
至於在得到結果後欲將之傳送至客戶端, 假設目標為 name = "content" 框架中 id = "result" 的區塊, 那麼伺服器傳回來給 robot 的頁面內容裡應該要包含控制 top. content. document. result 的 script. 不過較文雅的方式最好是設定好溝通的函數, 一般稱為 API. 在 robot 中呼叫 top. content. reply(), 而後在 content 中的 function reply() 對所在文件的 result 做控制. 這麼看來猶如遠端的 server 對 client 的文件作出控制, 也因此命名為 Remote Scripting. 茲以圖文描繪其輪廓如下:
<frameset rows="100%, 0%">
<frame src="content.htm" name="content">
<frame src="about:blank" name="robot">
</frameset>
| 我是 content, 裝個按鈕觸發下方框架詢問伺服器, 例如: ⇒ <span id = "result"> </span> 其中 button 可設定 onclick = "top.robot.location = 'date.php?event=movie'; " 加上 API: reply( ans ) { result.innerHTML = "沙織說: " + ans; } |
| 我是 robot, 事實上因高度為 0 而隱藏. 在詢問伺服器後傳回的網頁可能是: <body onload = "top.content.reply( 'no' )" > |
在 iframe 規格制訂出來以後, 再也不用大費周章地寫 frameset 只為了偷偷摸摸地安插 robot. 對於 iframe 而言, 主頁的 reply() 只要以 parent. reply() 即可呼叫. 加上使用方便門檻低, 難怪 iframe 在一般用途上廣受歡迎.
遺憾的是在下並無掌管任何能執行 CGI 的主機, 只好舉 阿尾的孤狗窩 中的公告區[註]為實例, 剖析其 script code. 該區塊由 iframe 建構, 雖無 request server 動作, 然其內含網頁在變更顯示數量時一併改變 iframe 尺寸, 也算是應用 RS 其中一個技巧. iframe 設定如下:<iframe id="annoBlock" align="center" width="100%"主頁 API 如下:
src="externAnno.html" marginheight="0" allowTransparency scrolling="no" frameborder="0"></iframe>function setContBlockHeight(num) {
在 externAnno.html 呼叫 API 的指令則是簡單的:
document.getElementById("annoBlock").style.height = strH;parent.setContBlockHeight (num);另外一方面, 其實 externAnno.html 算是一個功能完整的網頁, 只是在單獨開啟時會因找不到 parent. setContBlockHeight (num) 而發生錯誤喪失功能. 所以為求獨立運行, 在呼叫時不妨先檢查自身是否為框架頁, 語法例如:if( parent.location != location ) {呈現結果歡迎您移駕至寒舍 阿尾的孤狗窩 參考.
[註]撰寫此文時 externAnno.html 內容因為偷懶而暫採 String Array 方式加入, 但改成讀取外部 XML 是更理想的方式.
- Remote Scripting (by Prof. 張智星)
- Remote Scripting with IFRAME (on ADC)
- From Remote Scripting to AJAX (by Anthony Wong)
- 賜名給我,我就火了 (by 王建碩)




0 筆指教:
張貼意見