当前位置: 移动技术网 > IT编程>开发语言>Asp > ASP中Server.Execute和Execute实现动态包含(include)脚本的区别

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

2017年12月08日  | 移动技术网IT编程  | 我要评论
最近打算尝试一下在asp中实现mvc架构,肯定有人问我:asp都淘汰了,为什么还研究?这点我也知道,自从微软放弃asp 3.0转向asp.net后,asp已经远远落后于和它
最近打算尝试一下在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函数内部,那么在这个外部是无法访问的。
参考文档:《》 和《》 。
2011年11月23日更新
还有一种vbscript特有的写法叫做executeglobal,这个可以解决上文说的作用域问题,通过其执行的代码是全局有效的,但是要注意避免类、函数、过程或者变量的重定义覆盖问题。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网