直播中
图4-13 使用Execute和Transfer方法的屏幕
单击Server.Execute和Server.Transfer方法的按钮,提交到此窗体并重新装载该窗体。在这个页面顶部的脚本代码查看是哪个按扭被单击。如果是cmdExecute或cmdTransfer按钮,则把当前网页的路径写入到输出流中,然后调用相应的方法,并传送与该按钮相联系的文本框中的值,然后再把当前页面的路径写到输出流中。
…
If Len(Request.Form("cmdExecute")) Then
strPath = Request.Form("txtExecPath")
Response.Write "Currently executing the page: <B>" _
& Request.ServerVariables("SCRIPT_NAME") & "</B><BR>"
Server.Execute (strPath)
Response.Write "Currently executing the page: <B>" _
& Request.ServerVariables("SCRIPT_NAME") & "</B><BR>"
End If
If Len(Request.Form("cmdTransfer")) Then
strPath = Request.Form("txtTransferPath")
Response.Write "Currently executing the page: <B>" _
& Request.ServerVariables("SCRIPT_NAME") & "</B><BR>"
Server.Transfer (strPath)
End If
…
当单击Server.Excute方法的按钮时,会看到当前页面的路径,这是由上面代码中的第一条Response.Write语句创建并显示的。后面接着的内容是来自被执行的网页(another_page.asp)的一些输出内容。在这之后是第二个Response.Write语句的输出内容,这表明控制又回到了原先的网页,屏幕如图4-14所示:
图4-14 Server.Excute方法的演示
页面的两条水平线之间的段落(显示当前执行的网页为show_server.asp)来自原先的网页。在接下来的段落来自被执行的网页another_page.asp。下面是该页面的完整代码:
<%@ LANGUAGE=VBSCRIPT %>
<HR>
Currently executing the page: <B>another_page.asp</B><BR>
However the value of <B>Request.ServerVariables("SCRIPT_NAME")</B> is still <BR>
<B><% = Request.ServerVariables("SCRIPT_NAME") %></B>
because the <B>Request</B> collections hold<BR>
the same values as they had in the page that executed this one.<BR>
<FORM ACTION="<% = Request.ServerVariables("HTTP_REFERER") %>" METHOD="POST">
<INPUT TYPE="SUBMIT" NAME="cmdOK" VALUE=" ">
Return to the previous page<P>
</FORM>
<HR>
注意,该页面执行时,不能使用Request.ServerVariables(“SCRIPT_NAME”)获取它的路径,因为环境仍然是原网页的。我们不得不把页面名作为文本写入,因为实在没有办法可以从ASP环境中直接获取。
这里包括了一个返回前一个网页的按钮的原因是,通过在主网页中单击相对应的按钮,可以使用Server.Transfer方法调用这个页面。这次看到了完全相同的输出,只是没有第二次路径输出,因为是“传送”这个页面而不是“执行”该页面,所以控制不会回传给原先的网页,如图4-15所示:
图4-15 Server.Transfer的演示
(2) 从ASP执行SSI网页
目前有了一个方法,如果需要的话可在ASP网页中成功地使用SSI指令。虽然这种要求不常出现,但可实现。过去的问题是,由于在SSI网页(文件扩展名是.stm、.shtml和.shtm)中不能包含ASP代码,所以程序不能“无缝”地重定向回到原先的网页,必须增加一个按钮或链接,以装载原先的或另外的ASP网页。
现在,由于有了Server.Execute方法,可以执行一个SSI网页并且将控制自动返回到原先的网页,客户端意识不到这些过程正在进行。客户端只是看到原先的ASP网页和执行结果。来自于SSI网页的任何输出都“无缝”地插入到流中。当然,如果在SSI网页完成后,不想使原先的网页继续执行,可以使用Server.Transfer方法。
为了看到这个技术的执行,把前面使用过的CGI-SSI例子网页的虚拟路径输入到Server.Excute方法(或Server.Transfer方法)的文本框中。这个路径是“../ssi_cgi/ssi_cgi.stm”。在单击按钮对Execute或Transfer方法进行调用以后,将看到.stm网页已经执行,其中有SSI指令的结果。在来自ssi_cgi.stm的内容之后出现的是原先的网页的其余部分,虽然在图4-16中看不到,但可通过滚动条看到该内容。
图4-16 执行Server.Excute方法后的屏幕
3. SSI #exec指令的不足
遗憾的是Execute和Transfer方法一般不能与SSI的#exec指令一起工作,因为包含这个指令的.stm网页会在调用它的ASP网页的环境中运行。在大多数情况下,它需要运行于直接引用该网页的一个独立的环境中。
存在这样的限制真是遗憾,如果没有这种限制,我们通过Server.Execute执行的网页可以“不可见地”包含来自于ASP网页的#exec指令。对前面的通过net stop和net start命令停止和启动Indexing Service的示例来说,它可能是一种理想的解决方案。
但是,我们必须求助于老的和已经验证的方法。当用户单击一个按钮时,简单地使用Response.Redirect方法来打开相关的网页:
<%
‘Look for a command sent from the FORM section buttons
If Len(Request.Form(“cmdStop”)) Then
Response.Redirect(“exec/stop_cisvc.stm”)
End If
If Len(Request.Form(“cmdStart”)) Then
Response.Redirect(“exec/start_cisvc.stm”)
End If
%>
可以试着把使用#exec指令的一个SSI网页的虚拟路径输入到示例页面的Server.Execute和Server.Transfer方法的文本框中。前面使用过的#exec示例的虚拟路径是“../ssi_cgi/exe/start_cisvc.stm”和“../ssi_cgi/exec/stop_cisvc.stm”。