19-AJAX 與非同步傳輸

Download Report

Transcript 19-AJAX 與非同步傳輸

第十九章
AJAX 與非同步傳輸
張智星
[email protected]
http://mirlab.org/jang
台大資工系 MIR實驗室
JavaScript 程式設計與應用:用於伺服器端的ASP環境
本章大綱

大綱


本章介紹如何進行網頁的非同步傳輸,特別是著重於
AJAX 的原理及範例,並說明如何以 JavaScript
Framework 中最常被用到的 Prototype.js 來簡化 AJAX 的
設計及應用。
主題




19-1:簡介
19-2:使用隱藏式 iframe 的非同步傳輸
19-3:基本 AJAX 原理與範例
19-4:使用 Prototype.js 來進行 AJAX 網頁設計
2/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
19-1:簡介

本小節介紹AJAX的相關知識背景。
3/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
發展緣由



Web 基本上是一個分散的系統,所有的計算和處理,都由用
戶端和伺服器來共同完成,用戶端的電腦執行的是網頁中的
Client-side Scripts,而伺服器則是執行網頁中的 Server-side
Scripts。
在 http 的協定下,每當使用者發出一個 Request 之後,伺
服器就相執行網頁中的 Server-side Scripts (如 ASP),並
將結果傳回給用戶端,再由用戶端的瀏覽器來執行網頁中的
Client-side Scripts(如 JavaScript 或 VBScript),並將結果
顯示在螢幕上。
如果還要存取伺服器端的資料,就必須再一次經由表單的送
出,才能指揮伺服器做事,並將結果以新的網頁資料回 傳,
造成換頁,因此要保存原先網頁的資訊,比較麻煩。
4/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
非同步傳輸


目標:由 Client-side Scripts 所接收的事件(如滑鼠
點選某一按鈕)來指揮 Server-side Scripts 做事,
並在不換頁的情況下,將 Server-side Scripts 的執
行結果悄悄地送回 Client-side Scripts 並顯示結果於
同一個網頁。
可以使用以下幾種方式達成:



使用隱藏式的 iframe:這是一種比較傳統的方式,但是
使用方式也比較受限。
使用 AJAX:這是一種比較常用的方式,也比較有彈性。
亦可採用微軟的 Remote Scripting 來達成非同步傳輸,
但是這需要近端的機器安裝 Java,對使用者造成負擔,
因此比較不實用。
5/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
AJAX

AJAX 的全名是「Asynchronous JavaScript And XML
」,翻成中文是「非同步式的 JavaScript 與 XML」,
包含



HTML 及 CSS:負責顯示結果。
JavaScript:負責近端的事件擷取及資料處理,並大量運
用 DOM (Document Object Model) 來讀取由伺服器回傳
的資料,資料格式可能是 XML 或是 HTML。
XMLHttpRequest物件:負責以非同步的方式來執行遠端
的程式,並接收相關的結果。
6/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
AJAX優缺點

採用 AJAX 可以提供下列好處:



簡化網頁流程設計。
降低網路資料流量。
也有下列幾項缺點:


因為不換頁,因此無法使用「上一頁」、「下一
頁」來顯示所需的網頁。
搜尋引擎無法直接對動態資料建立索引,因此不
利於搜尋。
7/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
19-2:使用隱藏式 iframe 的非同步傳輸

本小節介紹如何利用隱藏的iframe來接收伺服
端的網頁,並將資料回傳到client端。
8/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-1

主題:使用 iframe 來進行非同步傳輸的簡單範例


Webpage: remote host, local host
程式碼重點
<iframe id="myHiddenFrame" style="display:none"></iframe>
var iframe = document.getElementById(‘myHiddenFrame’);
iframe.src = “serverAction01.asp”;

說明
 我們利用display:none將iframe隱藏,再由
JavaScript指定要連到server端的位置。
 此範例使用附檔名htm以顯示並沒有直接執行遠
端程式碼。
9/30
 下個範例是server端的處理方式。
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-2

主題:續19-1子網頁回傳訊息給母網頁


檢視子網頁: remote host, local host
程式碼重點
window.parent.showRetrievedInfo('<%=serverName%>'
, '<%=serverUrl%>', '<%=serverIp%>');

說明


子網頁會回傳訊息給隱藏iframe的母網頁。
使用 iframe 來進行非同步傳輸,是一個簡單可行的方式,
足以對付一般基本應用。但是此方法最大的缺點,是子網
頁無法支援 post 的資料傳送方式。
10/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
基本流程總結

母網頁利用隱藏的iframe(子網頁)來即時執
行伺服器端的程式。
iframe.src = “Server端網頁”;

子網頁將結果回傳給母網頁的函式。
window.parent.函式(<%ASP參數%>);

母網頁的函式藉由innerHTML的屬性,來修改
<div>標籤內容。
document.getElementById(‘DIV標籤ID’).innerHTML=顯示內容
11/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-3

主題:使用隱藏式iframe來查詢資料庫


Webpage: remote host, local host
程式碼重點
<script runat=server language=javascript src="sqlUtility.fun"></script>

說明


由於 SQL 指令含有空格,因此在使用 get 方式來設定網
址時,我們必須先將 SQL 指令送到 escape() 函數,以便
進行適當之編碼來避開可能造成錯誤之字元。
由於我們必須反覆用到資料庫的查詢,達成此功能的相關
函數是 getQueryResult(),定義於 sqlUtility.fun。
12/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-4

主題:查詢資料庫Server端網頁


檢視子網頁: remote host, local host
程式碼重點
if (sql.search(/^select/i)<0)

說明

由於我們不希望使用者去修改資料庫,因此會使
用通用運算式來檢查 SQL 指令,不是 "select" 開
頭,則認定是不合法的 SQL 指令並回傳警告訊息
「SQL command not started with SELECT is
disabled!」。
13/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
19-3:基本 AJAX 原理與範例

本小節介紹AJAX的基本原理以及如何應用。
14/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
AJAX 的使用方式

主要包含三個基本步驟:



近端(用戶端)的發送函數:負責在接收主網頁
的事件後,設定 AJAX 物件,並對伺服器發送
request 以啟動伺服器端程式碼的執行。
遠端(伺服器端)的程式碼:通常是一個 ASP 網
頁,負責在伺服器執行必要之步驟,例如檢查帳
號密碼,或是對資料庫進行查詢等。
近端(用戶端)的接收函數:負責接收伺服器的
執行結果,並將結果以非同步的方式顯示在主網
頁上。
15/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-5

主題:介紹AJAX使用原理的基本範例


Webpage: remote host, local host
說明




近端的發送函數:getServerTime()。
遠端的程式碼:showTime.asp。
近端的接收函數:displayTime()。
以下會分別說明這個範例的原理。
16/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
近端發送函數

近端的發送函數是 getServerTime(),主要負責當使
用者點選按鈕後,產生 AJAX 物件並設定之,然後
對伺服器發出 request

我們使用下列產生AJAX物件
ajax = new ActiveXObject("Msxml2.XMLHTTP");

對此物件設定接收伺服器的設定函式
ajax.onReadyStateChange=displayTime;

使用下列方式來設定 AJAX 物件的其它性質
ajax.open(“GET”, url, true);//傳遞方式, 網址, 是否為非同步

最後,送出AJAX命令
ajax.send("");
17/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-6

主題:範例19-5的遠端程式碼


連結:檢視原始檔
程式碼重點
today=new Date();
time=today.toString();
Response.write("<font color=red>"+time+"</font>");

說明

本例功能相當簡單,只是印出現在的時間
18/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
近端的接收函數(1)

檢查伺服器程式碼是否執行完畢
if (ajax.readyState==4)

說明

readyState 代表 ajax 目前的狀態
readyState 的值
說明
0
尚未啟始
1
已經建立連結
2
遠端已經收到要求
3
遠端程式碼處理中
4
處理完畢
19/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
近端的接收函數(2)

檢查伺服器回應函數是否執行無誤
if (ajax.status==200)

只有當網頁 showTime.asp 回傳的狀態碼是 200
時,才代表 showTime.asp 的執行無誤。
20/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
近端的接收函數(3)

將 AJAX 回傳的資訊指定給 <DIV>區塊內容
document.getElementById('showResult').innerHTML = ajax.responseText;

伺服器程式碼回傳的原始資訊,會原封不動地放
到 responseText 此性質中。如果伺服器回傳的
資訊是 XML 文件格式,我們可以由另一個性質
responseXML 來讀取 XML 文件內的各個物件。
21/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
19-4:使用 Prototype.js 來進行 AJAX 網頁設計

本小節介紹如何使用Prototype.js,讓AJAX可
以在不同的瀏覽器平台上使用。
22/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
Prototype.js



目前在網路上最常被用到的 JavaScript framework,就是
prototype.js,可由網址下載: http://prototype.conio.net
所謂的 framework,可以看成是原先 JavaScript 的應用程式
介面(API,或是 Appliation Program Interface),可以根
基於基本的 JavaScript 來提供更先進的功能。
prototype.js所提供的擴充功能如下:



AJAX:提供對於 AJAX 的支援,簡化了使用方式及流程,也提高了
AJAX 在各種不同瀏覽器的相容性。
DOM:延伸了 DOM 的物件和功能。
JSON(JavaScript Object Notation):支援 JSON 的資料格式,比
XML 易於瞭解與讀寫。
23/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-7

主題:使用Prototype.js實作AJAX範例


Webpage: remote host, local host
說明


資料庫連結:test.mdb
這是一個比較老的資料庫,你也可以輸入其他歌
手看看,例如周華健、巫啟賢、林憶蓮、莫文蔚、
陶晶瑩等。
24/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
近端發送函數(1)

近端的發送函數:sendQuery()

此函數定義了遠端的程式碼網頁 queryDb01.asp,
同時也加入了參數列 singerName=鄧麗君,最後
產生 AJAX 物件並定義相關參數,送到遠端執行。
其中有幾點要注意:


「$F('singerName')」是 Prototype.js 所提供的簡化語
法,其功能全等於
「document.getElementById('singerName').value」。
如果我們在 $() 之內輸入多個 id,此函數會回傳對應
這些 id 的物件所成的陣列。
25/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
近端發送函數(2)

產生 AJAX 物件的第二個參數是
method:‘post’, parameters:queryString, onComplete:showQueryResult
此參數全等於一個具有三個欄位的物件,因此我們甚
至可以將 sendQuery() 函數的第三列敘述:
var ajax = new Ajax.Request(url, {method:'post',
parameters:queryString, onComplete:showQueryResult});
改成:
var ajaxParam = new Object();
ajaxParam.method='post';
ajaxParam.parameters=queryString;
ajaxParam.onComplete=showQueryResult;
var ajax = new Ajax.Request(url, ajaxParam);
26/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-8

主題:範例19-7的遠端程式碼



連結:檢視原始檔
程式碼重點
說明

database="test.mdb";
sql="SELECT * from Singer where ChineseName = ‘“
+Request("singerName")+"'“;
outStr=getFirstRecordFromQueryResult(database, sql);
Response.write(outStr);
此程式碼接收使用者輸入的歌手名字,造出 SQL
命令,並送入資料庫查詢,並將查詢結果印出來。
27/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
近端接收函數

近端的接收函數:showQueryResult()

在此函數中,我們只使用一列程式碼:
Element.update('queryResult', xmlHttpObj.responseText);

這也是 Prototype.js 所提供的簡化語法,其功能全等於 :
document.getElementById('queryResult').innerHTML=
xmlHttpObj.responseText

由於資料庫和網頁編碼的不一致,常會導致亂碼的產生,
因此我們這個範例的兩個檔案(ajaxViaPrototype01.htm
和queryDb01.asp),都是採用 UTF-8 的編碼,一般常用
的文字編輯器,例如記事本(notepad.exe)及 UltraEdit,
都支援 UTF-8 文字檔的檢視和編輯。
28/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-9

主題:使用prototype.js中的Updater()來達成AJAX


Webpage: remote host, local host
程式碼重點
var ajax = new Ajax.Updater('queryResult', url,
{method:'post', parameters:queryString});

說明

Ajax.Updater() 的第一個參數是 ‘queryResult’,這就是代
表回傳資料將會被指定到
document.getElementById(‘queryResult’).innerHTML,
因此我們就不必另外在寫一個負責顯示結果的函數。
29/30
JavaScript 程式設計與應用:用於伺服器端的ASP環境
範例19-10

主題:使用Responders.register做出請稍候的效果


Webpage: remote host, local host
程式碼重點
Ajax.Responders.register ({
onLoading: function(){
Element.update(‘queryResult’, ‘<font color=red>查詢資料中,
請稍候...</font>');},
onComplete: function(junk, xmlHttpObj){
Element.update('queryResult', xmlHttpObj.responseText);}});

說明

onLoading 事件的函數可以不斷印出「資料處理中,請稍
後...」之訊息,而對應至 onComplete 事件的函數則可以
顯示最後查詢結果。
30/30