IIS找到ASP文件,提交給ASP引擎(一般是ASP.DLL)處理等等,需要的朋友可以參考下首先我們先來了解一下ASP頁面執行的流程
1.IIS找到ASP文件,提交給ASP引擎(一般是ASP.DLL)處理。
2.引擎開啟這個ASP文件,找出<%和%>之間的內容,當然還有<script runAt=server>和對應的</script>之間的內容,這些內容稱為腳本區塊。只有腳本區塊裡的內容被引擎解析,其他內容不管,作為沒有意義的字元插在腳本區塊之間。有必要說明一下的是,其實被解析的內容還不止這些,<!--#include ***-->類別的伺服器端包含檔案也是由引擎包含進來並加以處理的。如果你讀的程式比較多,你還會知道有的runAt屬性標註為Server的<object>物件也是會被處理的,這裡不做深入討論。
3.引擎執行腳本區塊中的腳本,這些伺服器端的腳本是作為一個整體被執行的,也就是說,可以寫出如下的程式碼:
複製代碼代碼如下:
<%
Dim i
For i=1 to 5
%> Hello World!
<% Next %>
引擎並不會將這些腳本區塊分開解析,而使兩個腳本區塊都發生語法錯誤。所以我們得到以下結論:並非所有非伺服器腳本的程式碼都會被傳送到客戶端,有可能這段非伺服器腳本的程式碼被腳本區塊限制了。伺服器是一定不會操心客戶端腳本的執行問題的,但是可以透過伺服器端的腳本輸出不同的客戶端腳本。
4.最終引擎產生了一個文字流,或者說是腳本的執行結果,可以認為這是一個字串,就是發送到客戶端瀏覽器的網頁的程式碼。客戶端瀏覽器將頁面顯示出來,此時頁面的源代碼(源文件)是不包含伺服器端的腳本的,但包含了伺服器端腳本的執行結果(這是顯然的)。
<% … %> 與<script runat=server>…</script>
它們都是伺服器端的腳本,同時被處理執行。他們執行時是作為一個整體的。
<% … %> 與<script language=…>…</script>
前者是伺服器端腳本,後者是客戶端腳本。前者先執行,後者後執行。
其實也不盡然,二者的腳本是有可能在同時被執行的,但空間不同,仍然是:前者在伺服器上執行,後者在客戶端瀏覽器裡執行。前者在邏輯上一定提前於後者執行。同時我們也得到結論:在同一個頁面的執行中,客戶端腳本無論如何不能反饋給伺服器端腳本,也就是說,客戶端瀏覽你的留言本並且提交新留言或者是任何客戶端腳本獲取的值都不可能在同一次伺服器回應中被處理。
關於元件的調用
注意伺服器端腳本和客戶端腳本都是腳本,自然可以建立xmlhttp元件、ADODB.Connection元件等,但不是放在哪裡都可以的。
xmlhttp如果用於伺服器的抓取網頁(例如採集)就要在伺服器腳本裡創建了,而如果是用於客戶端的ajax無刷新而後台訪問伺服器端的頁面,那麼就是運行於客戶端的了,自然在客戶端創建。
ADODB.Connection元件用於存取資料庫,一般來說在伺服器端創建,畢竟是伺服器端的asp程式在跑資料庫的數據,但如果你的資料庫真的是在客戶端連接的,那麼就毫無疑問在客戶端腳本裡創建了。
總之,矛盾著的事物及其每一個面向各有其特徵。不同事物有不同的矛盾;同一事物在發展的不同過程和不同階段上有不同的矛盾;同一事物中的不同矛盾、同一矛盾的兩個不同方面各有其特殊性(看不懂的可以略去不看……)。這項原則要求我們堅持具體問題具體分析原則,在矛盾普遍性原則的指導下,具體分析矛盾的特殊性,並找出解決矛盾的正確方法。反對千篇一律地採用一種方法來解決不同事物的矛盾。一把鑰匙開一把鎖,到什麼山唱什麼歌講的就是這個道理。
伺服器端VBScript腳本建立物件使用Server.CreateObject(className)方法,客戶端VBScript腳本建立物件使用CreateObject(className)方法。
典型錯誤
複製代碼代碼如下:
<%
Function TSize(b)
'這是我自訂的函數
TSize=中國
end function
%>
<a href=javascript:<%TSize('變數')%> >點這裡要使用我定義的函數</a>
錯誤分析:
混淆了伺服器端腳本和客戶端腳本的差異。實際執行時我們會發現,客戶端根本沒有收到什麼TSize之類的程式碼,因為TSize是伺服器端的程序,被引擎處理之後(注意引擎對於函數的處理,純粹是給伺服器端腳本呼叫的,不會發回到客戶端)就消失了,不可能在客戶端運作。這就是說,客戶端腳本無法直接呼叫伺服器端腳本的函數。
事實上,這個程式是有語法錯誤的,引擎處理這段內容的時候先找到了<%和%>之間的內容,也就是<%TSize('變數')%>,顯然這段內容不符合VBScript的語法規則。嗯,改成<%=TSize(變數)%>在伺服器端腳本就沒有語法錯誤了,這時TSize函數可以正常回傳值中國,於是客戶端收到的href屬性是這樣寫的:javascript:中國,是無法執行的。
伺服器端腳本對客戶端腳本的影響
前面已經說過了,伺服器端腳本在邏輯上是提前於客戶端腳本的執行的,因此這樣的程式碼是可行的:
複製代碼代碼如下:
<%
Dim i
For i=1 to 5
Response.Write <script type=text/javascript> _
& alert('Hello World! & i & ')</script>
Next
%>
關於Response.Redirect與javascript的執行問題
注意以下程式碼的寫法是錯誤的:
複製代碼代碼如下:
<%
Response.Redirect index.asp
Response.Write <script type=text/javascript> _
& alert('密碼錯誤!')</script>
%>
這是一個常見的錯誤,編寫者常常以為,這樣寫程式碼可以使客戶端先彈出密碼錯誤的提示然後轉向到index.asp,事實上這不可能發生,即使將兩行程式碼順序交換,也不可能達到這種效果。
究其原因,和伺服器對於兩行程式碼的處理方式有關。這兩行程式碼不可能同時起作用。
Response.Write是向客戶端發送一段文本,這段文本的內容可以是一段腳本,那麼客戶端瀏覽器收到後可以執行這段腳本,注意,要收到之後才能執行。
而Response.Redirect是向客戶端發送了一個HTTP頭信息(什麼是HTTP頭信息?這麼說吧,比如對客戶端Cookies的寫入是HTTP頭信息,HTTP頭信息在HTTP的主體之前發回客戶端瀏覽器,這就是為什麼有時我們把伺服器的緩衝關閉之後修改Cookies會出錯的原因,因為主體已經開始傳送,不允許發送HTTP頭訊息了。 .Write向緩衝裡寫入了多少內容,一旦呼叫Response.Redirect,將會清空緩衝,並且向客戶端瀏覽器發送這個頭指令。如果動態追蹤程式的執行,我們也會發現,在呼叫了Response.Redirect之後,程式停止執行了,所以注意伺服器端程式在呼叫Response.Redirect之前要做好資料連線的關閉等操作。
那麼上面的例子應該怎麼修改呢?如果你不願意修改那個index.asp以加入腳本提示的話,那麼只能將轉向指令放到客戶端腳本中執行,就像這樣:
複製代碼代碼如下:
<%
Response.Write <script type=text/javascript> _
& alert('!');location.href='index.asp'</script>
%>