熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

詳解ASP腳本的執行順序

2013-11-13 10:06:35  來源: .NET編程 

  首先我們先來了解一下ASP頁面執行的流程

  IIS找到ASP文件提交給ASP引擎(一般是ASPDLL)處理

  引擎打開這個ASP文件找出<%和%>之間的內容當然還有<script runAt=server>和對應的</script>之間的內容這些內容稱為腳本塊只有腳本塊裡的內容被引擎解析其他內容不管作為沒有意義的字符插在腳本塊之間有必要說明一下的是其實被解析的內容還不止這些<!——#include ***——>類的服務器端包含文件也是由引擎包含進來並加以處理的如果你讀的程序比較多你還會知道有的runAt屬性標注為Server的<object>對象也是會被處理的這裡不做深入討論

  引擎執行腳本塊中的腳本這些服務器端的腳本是作為一個整體被執行的也就是說可以寫出如下的代碼

  <%
Dim i
For i= to
%> Hello World!
<% Next %>

    引擎並不會將這些腳本塊分開解析而使兩個腳本塊都發生語法錯誤所以我們得到如下結論並非所有非服務器腳本的代碼都會被發送到客戶端有可能這段非服務器腳本的代碼被腳本塊限制了服務器是一定不會操心客戶端腳本的執行問題的但是可以通過服務器端的腳本輸出不同的客戶端腳本

  最終引擎產生了一個文本流或者說是腳本的執行結果可以認為這是一個字符串就是發送到客戶端浏覽器的網頁的代碼客戶端浏覽器將頁面顯示出來此時頁面的源代碼(源文件)是不包含服務器端的腳本的但包含了服務器端腳本的執行結果(這是顯然的)

  <% … %> 與 <script runat=server>…</script>

  它們都是服務器端的腳本同時被處理執行他們執行時是作為一個整體的

  <% … %> 與 <script language=>…</script>

  前者是服務器端腳本後者是客戶端腳本前者先執行後者後執行

  其實也不盡然二者的腳本是有可能在同時被執行的但空間不同仍然是前者在服務器上執行後者在客戶端浏覽器裡執行前者在邏輯上一定提前於後者執行同時我們也得到結論在同一個頁面的執行中客戶端腳本無論如何不能反饋給服務器端腳本也就是說客戶端浏覽你的留言本並且提交新留言或者是任何客戶端腳本獲取的值都不可能在同一次服務器響應中被處理

  關於組件的調用

  注意服務器端腳本和客戶端腳本都是腳本自然都可以創建xmlhttp組件ADODBConnection組件等但是並不是放在哪裡都可以的

  xmlhttp如果用於服務器的抓取網頁(比如采集)就要在服務器腳本裡創建了而如果是用於客戶端的ajax無刷新而後台訪問服務器端的頁面那麼就是運行於客戶端的了自然在客戶端創建

  ADODBConnection組件用於訪問數據庫一般來說在服務器端創建畢竟是服務器端的asp程序在跑數據庫的數據但如果你的數據庫真的是在客戶端連接的那麼就毫無疑問在客戶端腳本裡創建了

  總之矛盾著的事物及其每一個側面各有其特點不同事物有不同的矛盾同一事物在發展的不同過程和不同階段上有不同的矛盾同一事物中的不同矛盾同一矛盾的兩個不同方面各有其特殊性(看不懂的可以略去不看……)這一原理要求我們堅持具體問題具體分析原則在矛盾普遍性原理的指導下具體分析矛盾的特殊性並找出解決矛盾的正確方法反對千篇一律地采用一種方法解決不同事物的矛盾一把鑰匙開一把鎖到什麼山唱什麼歌講的就是這個道理

  服務器端VBScript腳本創建對象使用ServerCreateObject(className)方法客戶端VBScript腳本創建對象使用CreateObject(className)方法

  典型錯誤

<%
Function TSize(b)
這是我自定義的函數
TSize=中國
end function
%>
<a javascript:<%TSize(變量)%> >點這裡要使用我定義的函數</a>

    錯誤分析

  混淆了服務器端腳本和客戶端腳本的區別實際執行時我們會發現客戶端根本沒有收到什麼TSize之類的代碼因為TSize是服務器端的程序被引擎處理之後(注意引擎對於函數的處理純粹是給服務器端腳本調用的不會發回到客戶端)就消失了不可能在客戶端起作用這就是說客戶端腳本無法直接調用服務器端腳本的函數

  事實上這個程序是有語法錯誤的引擎處理這段內容的時候先找到了<%和%>之間的內容也就是<%TSize(變量)%>顯然這段內容不符合VBScript的語法規則改成<%=TSize(變量)%>在服務器端腳本就沒有語法錯誤了這時TSize函數可以正常返回值中國於是客戶端收到的href屬性是這樣寫的javascript中國是無法執行的

  服務器端腳本對客戶端腳本的影響

  前面已經說過了服務器端腳本在邏輯上是提前於客戶端腳本的執行的因此這樣的代碼是可行的

<%
Dim i
For i= to
ResponseWrite <script type=text/javascript> _
& alert(Hello World! & i & )</script>
Next
%>

  關於ResponseRedirect與javascript的執行問題

  注意以下代碼的寫法是錯誤的

<%
ResponseRedirect indexasp
ResponseWrite <script type=text/javascript> _
& alert(密碼錯誤!)</script>
%>

    這是一種常見的錯誤編寫者常常以為這樣寫代碼可以使客戶端先彈出密碼錯誤的提示然後轉向到indexasp事實上這不可能發生即使將兩行代碼順序交換也不可能達到這種效果

  究其原因和服務器對於兩行代碼的處理方式有關這兩行代碼不可能同時起作用

  ResponseWrite是向客戶端發送一段文本這段文本的內容可以是一段腳本那麼客戶端浏覽器收到後可以執行這段腳本注意要收到之後才能執行

  而ResponseRedirect是向客戶端發送了一個HTTP頭信息(什麼是HTTP頭信息?這麼說吧比如對客戶端Cookies的寫入是HTTP頭信息HTTP頭信息在HTTP的主體之前發回客戶端浏覽器這就是為什麼有時我們把服務器的緩沖關閉之後修改Cookies會出錯的原因因為主體已經開始傳送不允許發送HTTP頭信息了信息的內容告訴客戶端浏覽器應該跳轉頁面浏覽注意這個Redirect信息是立刻起作用的也就是說這個Redirect信息具有排他性在緩沖打開的情況下無論已經使用ResponseWrite向緩沖裡寫入了多少內容一旦調用ResponseRedirect將會清空緩沖並且向客戶端浏覽器發送這個頭指令如果動態跟蹤一下程序的執行我們還會發現在調用了ResponseRedirect之後程序停止執行了所以注意服務器端程序在調用ResponseRedirect之前要做好數據連接的關閉等操作

  那麼上面的例子應該怎樣修改呢?如果你不願意修改那個indexasp以加入腳本提示的話那麼只能將轉向指令放到客戶端腳本中執行就像這樣

<%
ResponseWrite <script type=text/javascript> _
& alert(!);location</script>
%>


From:http://tw.wingwit.com/Article/program/net/201311/12587.html
  • 上一篇文章:

  • 下一篇文章:
  • Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.