ASP指令碼的執行順序詳細說明

來源:互聯網
上載者:User

首先我們先來瞭解一下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頭資訊了。),資訊的內容告訴用戶端瀏覽器應該跳轉頁面瀏覽,注意,這個Redirect資訊是立刻起作用的,也就是說這個Redirect資訊具有排他性,在緩衝開啟的情況下,無論已經使用Response.Write向緩衝裡寫入了多少內容,一旦調用Response.Redirect,將會清空緩衝,並且向用戶端瀏覽器發送這個頭指令。如果動態跟蹤一下程式的執行,我們還會發現,在調用了Response.Redirect之後,程式停止執行了,所以注意伺服器端程式在調用Response.Redirect之前要做好資料連線的關閉等操作。

那麼上面的例子應該怎樣修改呢?如果你不願意修改那個index.asp以加入指令碼提示的話,那麼只能將轉向指令放到用戶端指令碼中執行,就像這樣: 複製代碼 代碼如下:<%
Response.Write "<script type=""text/javascript"">" _
& "alert('!');location.href='index.asp'</script>"
%>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.