精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● ASP>>远程脚本调用>>Remote Scripting进阶教程(客户端脚本调用服务器端脚本)

主题:Remote Scripting进阶教程(客户端脚本调用服务器端脚本)
发信人: qcrsoft(网痞)
整理人: i_am_trueman(2003-10-28 00:01:14), 站内信件
  概述

借助于 remote scripting,开发者现在就可以创建无缝的(seamless)、交互的 Web 应用程序了,在该应用程序中,浏览器可以在不用重新加载 Web 页的情况下调用服务器上的脚本。 

在 remote scripting 之前,为了与服务器交互作用,开发者必须要求用户重新对所调用页进行加载,而且经常是多次加载。这样就造成服务器使用上的慢速、不连贯、用户切身体验和效率低。 

Remote scripting 使得浏览器和 Web 服务器之间可以有更多客户/服务器类型的交互作用。例如,当在某个 Web 页上填写一张表格时,用户必须经常、多次重新加载整个页,才能使应用程序对输入项进行验证。借助于 remote scripting,Web 应用程序现在就可以在用户仍在填充表格的其余部分时,对数据进行验证,而无需对该页进行重新加载。特别指出,脚本必须首先对某个要连接的服务器页进行确认,然后才能将调用传输到服务器。任何来自于调用的返回值都传回到原始脚本中。



使用 Remote Scripting

Remote scripting 在 Web 应用程序中使用户具有将两个 scripting 平台综合到一个主页中的能力。用户可以创建客户脚本来控制应用程序的用户接口,而且如果用户正在使用 Microsoft Internet Explorer 4.0 的话,还可以利用 Dynamic HTML (DHTML) 的强大功能。同时,用户可以在自己的服务器上运行脚本以执行服务器端的任务,包括数据库查询、中层业务逻辑等等。由于客户页仍处于活动状态时,remote scripting 就在服务器上运行,因此用户脚本作了很大程度的简化,而且应用程序可以显示一个更丰富、响应更迅速的用户接口。



远程执行服务器脚本

复杂的 Web 应用程序既调用客户脚本又调用服务器脚本。客户脚本经常用于对应用程序的用户接口进行编程──例如,为了动态改变 Web 页文本,对用户动作,比如双击作出反应,并执行诸如验证这样的面向客户的任务。客户脚本在浏览器中局部执行,这样就向用户提供了一种生动的、反应迅速的接口。

对比来说,服务器脚本是用来对某个应用程序的末段编程的。这经常引起对某个数据库的存取动作,或者执行中间层业务逻辑。服务器脚本也用于创建较大范围的应用程序:也就是可能通过多种不同类型的浏览器(每个都有不同存取能力)进行存取的应用程序。

但是客户和服务器脚本是互斥的。当某个页首次请求时,服务器可能运行服务器脚本,并将页传递给浏览器,然后浏览器就可以运行客户脚本。不过,如果该页上的服务器脚本有必要再次运行的话,那么必须将该页提交回服务器,服务器可以有效地重新运行该页。对页面上控件状态和脚本中值的维护可能涉及到在浏览器和服务器之间来回传递信息的一个复杂的 scripting 过程。另外,客户和服务器之间的折返过程涉及到显示某个应用程序的重载过程。

一种折衷方案是 remote scripting。Remote scripting 使得用户可以在客户脚本中工作,但要调用某个 ASP 页中的方法(函数或者例程)。实际上,用户可以象调用本地例程那样调用服务器脚本,不过它们仍然运行在服务器上,并具有对服务器能力的所有存取权限。由于用户从不把当前页留作调用服务器脚本之用,因此页的状态仍然保持。

用户可以在下列任务中使用 remote scripting: 

当用户继续和某个数据输入表单交互作用时,服务器上的数据检查和数据验证。


更新来自服务器的页面中的信息而无须刷新屏幕。 
Remote Scripting 如何工作

Remote scripting 是作为一个函数库来实现的,当用户希望运行某个服务器方法时,用户从客户脚本中调用这些函数。当用户调用某种服务器方法时,请求即被传递到浏览器中异步运行的一个代理过程中(在实现过程中,代理是作为一个 Java applet 来实现的。)该代理过程发送一个请求到包含用户调用方法的 ASP 页的服务器中。

服务器加载 ASP 页,而且该 ASP 页上的一个特殊例程将用户的请求调度到正确函数。如果方法有返回值,那么该值即被发送回代理过程,该过程将之包装为一个对象 ──一个调用对象 ──它包含了返回值以及其他有用信息的属性。

当用户在客户脚本中对服务器方法进行调用时,可以在两种方式中选择其一来完成: 

同步 用户脚本调用远程过程,并等待其返回。如果用户在处理之前需要远程过程结果的话,那么就有必要这么做。


异步 用户脚本对某个远程脚本进行调用,然后继续处理。该页保持有效状态,以便于用户处理。如果某个调用要持续较长一段时间,那么就有必要使用异步调用。 
Remote Scripting 的部件
为了实现 remote scripting,除了用户自己的客户 (.htm) 文件和服务器 (.asp) 文件外,还需要下面的文件: 

Rs.htm 包含了用户在自己的 .htm 文件中初始化 remote scripting、执行远程过程、检查远程调用状态,以及获得方法结果时所要使用的方法。


Rs.asp 包含了用户在 .asp 文件中初始化服务器端的 remote scripting,以及在自己的页中调度到适当函数时所要调用的方法。


Rsproxy.class 包含客户和服务器页之间通信时 applet 的 Java 类文件(对象代码)。 
这些文件充当用户可以在自己的文件中使用的文件库。一般说来,用户只需要简单地将相关文件(Rs.htm 或者 Rs.asp)包括进自己的客户或者服务器页中,然后遵照所需调用方法进行处理。有关详细信息,请参阅 在客户页中使得 Remote Scripting 有效 以及 在服务器页中使得 Remote Scripting 有效。

在用户的客户页中,用户引用 Rs.htm,这使得该文件中的方法对于用户服务器脚本来说是有效的。对 Rsproxy applet 的调用就在这些方法中。当用户创建服务器页的时候,用户将服务器端的一个 INCLUDE 语句 ─ 该语句引用 Rs.asp 文件 ─ 包括进去。伴随客户文件中的 Rs.htm,这样做使得所需要的方法在服务器页上成为有效的。

所有文件都必须在服务器上是有效的。用户可以将它们放置到任何合适的地方。不过,对于用户的客户和服务器文件来说,当它们从服务器发出请求时,路径都必须是有效的。缺省的情况是,remote scripting 过程假设这些文件在用户服务器或者工程的虚拟根目录外的一个名为 _ScriptLibrary 的文件夹中是有效的。如果用户不将它们放到那里,那么要特别注意它们的路径,因为在创建客户和服务器页时,用户需要指定之。

Remote Scripting 和安全性
Remote scripting 提供和 Java applet 或 IFrames 同样级别的安全性。为了确保 remote scripting 不违反服务器安全性,用户不能将结构化数据(包括对象)作为参数传递给某个服务器文本来执行。另外,用户进行 remote scripting 调用的服务器必须和用户请求包含该请求的客户页的服务器是同一个。



使 Remote Scripting 在客户页中有效

在您能使用 remote scripting 来调用服务器脚本之前,必须将 remote scripting 能力添加到用户的客户页中。使用来自于客户脚本的 remote scripting 所需的例程包含在 Rs.htm 文件中。用户必须将该文件包含到自己的客户页中。另外,用户必须调用一个方法来启动 remote scripting applet。

为了使得 remote scripting 有效 

创建一个空的 JavaScript 脚本块──它引用 Rs.htm 文件,如下例所示:
<SCRIPT LANGUAGE="JavaScript" src="../_ScriptLibrary/RS.HTM">

要确保所指定 Rs.htm 文件的路径是正确的。该脚本块可以出现在用户客户页的任何地方,但必须在一个这样的块中──它在用户调用某个远程过程之前执行。 

创建第二个 JavaScript 脚本块,并在这个块中调用方法 RSEnableRemoteScripting。缺省的情况是,该方法假定 Rsproxy.class applet 在一个叫做 _ScriptLibrary 的文件夹中,而且刚好在用户服务器或者工程的虚拟根目录的下级目录。如果不是这样的话,那么您必须将路径传递到方法调用中的 Rsproxy.class 文件中。
这个包含 RSEnableRemoteScripting 的脚本块必须出现在文档的主体部分,因为它创建包含对 Rsproxy.class 引用的 <APPLET> 标记。必须将之放在包括 Rs.htm 文件的脚本块之后。您也可以将之放到 <BODY> 标记的后面,如下例所示: 

<BODY>
<SCRIPT LANGUAGE="JavaScript">
RSEnableRemoteScripting("../_ScriptLibrary")
</script>

<!-- 这里是 .htm 文件的其余部分 -->

注意 RSEnableRemoteScripting 所创建的 <APPLET> 标记并不出现在您的页面中──即使您在自己的浏览器中查看该页的源程序。 

带有有效 remote scripting 的梗概客户页是这样的:

<HTML>
<标头>
<标题>Remote Scripting 测试</标题>
</标头>

<主体>
<SCRIPT LANGUAGE="JavaScript" src="../_ScriptLibrary/RS.HTM"></脚本>
<SCRIPT LANGUAGE="JavaScript">
RSEnableRemoteScripting("../_ScriptLibrary")
</脚本>
<H1>Remote Scripting 客户页</H1>
这是 remote scripting 示例客户页中的文本。
</主体>
</HTML>

以此方式设置了客户页之后,用户就可以在服务器页上添加调用远程过程的脚本了。有关如何进行的详细信息,请参阅 同步调用 Remote Scripting 方法以及 异步调用 Remote Scripting 方法。关于如何设置服务器页以便于接收 remote scripting 调用的详细信息,请参阅在服务器页中使得 Remote Scripting 有效。



除了对客户页进行配置以便于调用远程脚本外,您还必须对自己的服务器页进行配置,以便于对它们进行接收。其做法包括下面这些步骤: 

包含 remote scripting 服务器库,并对其进行初始化。


编写客户页能调用的函数或者例程。


将自己的函数和例程显露为方法。 
缺省的情况是,客户脚本所调用的某个 ASP 页并不显示在浏览器中──而是简单地在服务器上执行并将结果送到客户端。因此,作为规则,您无需在 ASP 页中包括进任何 HTML 文本,而只需脚本。不过,还是有可能在某个 ASP 页上调用包括 HTML 文本的方法并作正常显示的,只要您初始化了 remote scripting 服务器库,并用下面描述的技巧显露页的方法。

包括并初始化 remote scripting 服务器库 

创建服务器端引用 Rs.asp 文件的 INCLUDE 语句,如下例所示:
<!--#INCLUDE FILE="../_ScriptLibrary/RS.ASP"-->

确保为 Rs.asp 文件指定正确路径。INCLUDE 语句可以出现在用户文件的任何位置。 

将一个调用插入到RSDispatch方法中,当您从客户脚本调用服务器脚本时,可用该方法找到正确过程。该调用可能看起来如下所示:
<% RSDispatch %>

RSDispatch 调用必须是运行在该页上的第一个服务器脚本。按惯例,典型做法是将其放到文件头部。 

在合适的初始化动作中,创建用户将从客户脚本中作为方法调用的函数或者例程。您可以用任何脚本语言书写过程。过程可以接受任意数目的参数,但参数只可以为字符串、数字、日期,或者其他简单数据类型──客户不能将结构化数据(例如,对象或者数组)作为参数。

注意 当您将参数从客户脚本传递到服务器脚本时,它们即被转换为字符串。如果用户期望自己的服务器方法中有不同数据类型,可以在方法脚本内部转换之。

在服务器脚本中创建了过程后,您必须将它们作为方法显露出来。为了达到该目的,您可以创建一个 JavaScript 公共描述对象,并列出用户希望显露的方法。

显露方法 

创建一个 public_description 对象,该对象为您的方法指定构造函数。下面的示例命名构造函数为 MyServerMethods:
<SCRIPT LANGUAGE="JavaScript">
var public_description = new MyServerMethods();

创建您在 public_description 对象中指定的构造函数。在构造函数内部,指定用户希望显露的方法名,以及它们相应的函数或者例程名。用户所使用的语法取决于用户是在 JavaScript 中还是在 VBScript 中创建自己的方法。可使用下面的语法:
functionconstructor(){
this.methodName = functionName //对于 JavaScript 方法来说
// 对于用 VBScript 书写的方法,使用下面的语法
this.methodName = Function('p1','p2','return functionName(p1,p2)') 
}
注意 JavaScript 是大小写敏感的,因此用户必须根据约定正确大写。 

其中: 

methodName 将被显露的方法名。


functionName 服务器页中实现 methodName 的函数名。 


p1, p2 传递给方法的参数列表──如果有参数的话。仅当该方法在 VBScript 中实现时,才能以这种方式显式地声明参数。参数名在构造函数内必须是一致的,但不需要和用户在方法本身中所使用的参数名匹配。用户不需要显式地声明传递给 JavaScript 中所实现方法的参数。 
下面的示例显示了一个完整的 ASP 页,该页显露两个方法,square 和 add,这可以从客户脚本中调用。square 方法是在 JavaScript 中实现的,而 add 方法则是在 VBScript 中实现的。

<% RSDispatch %>
<!--#INCLUDE FILE="../_ScriptLibrary/RS.ASP"-->

<SCRIPT RUNAT=SERVER LANGUAGE="JavaScript">
var public_description = new MyServerMethods();
function MyServerMethods()

this.square = squareNumber;
this.add = Function( 'n1','n2','return addNumbers(n1,n2)' );
}

function squareNumber(numberToSquare){
return numberToSquare * numberToSquare;
}
</SCRIPT>

<SCRIPT RUNAT=SERVER LANGUAGE="VBScript">
Function addNumbers(num1, num2)
' 数据类型发生转换,因为它们作为字符串进行传递
addNumbers = CInt(num1) + CInt(num2)
End Function
</SCRIPT>


原著:歪书生
来自:chinaasp.com

[关闭][返回]