在服务器和客户之间传输数据

80酷酷网    80kuku.com

  服务器|数据


     在本章的开始,已经向大家提供了一张RDS的组件框图,确定了哪些组件是客户端的,以及哪些组件是服务器端的。在上一节,集中介绍了客户端组件,即数据控件,因为它们是使用RDS最简单的方法。它们允许从服务器向客户机无缝地传输数据,同时也提供了一种在Web页面上处理数据的简易方法。为了获得服务器上的数据,只需要设置几个属性,调用一、两个方法就足够了。
    使用数据控件存在的问题在于它们获取数据的能力相对有限,即缺乏灵活性。对于RDS数据控件,必须通过参数,比如Connect i o n和SQL,指定连接和查询的细节,这把我们限制在数据库和简单的查询上。此外,用户还能看到这些参数,因此在使用RDS数据控件时存在一个潜在的安全漏洞。虽然属性U R L通过指定实际的数据源,而不是获取数据的场所,部分解决了这个问题,但仍然存在着缺陷。用户依旧可以获取U R L,直接读取数据,而这并不是我们所希望的。
    IE 5.0 的引入使访问X M L数据变得更为容易,因此以后X M L数据肯定会广泛使用。与RDS数据控件的U R L属性一样,用户也能直接读取数据,因为数据源的名称对他们是可见的。
    因此,下面一些问题需要考虑。
    ? 需要一种安全的方法检索服务器端数据,并在客户端使用它们。
    ? 需要一种更新数据的方法。
    ? 不损失灵活性。
    这些问题的解决方法是使用组件。组件允许封装对所有数据的访问,包括数据源,确保只在Web页面上显示数据。可以隐藏连接的细节,因为它们在组件内部,不会暴露给用户,所以安全性不会受到损害。也可以创建自己的组件来更新数据,这样保留了可更新数据的灵
活性。
    此外又增加了安全性,因为在客户端访问服务器组件之前,需要修改注册表。这确保只创建所需的组件,阻止用户上载组件,然后从服务器访问他们。稍后将会看到如何修改注册表。
10.3.1 基于服务器的组件
    在这里并不打算大篇幅地讨论如何创建组件,因为本书后面的部分章节已经覆盖了这些内容,这里将介绍一些十分简单的用于服务器组件的代码。这有助于说明将要使用的RDS例子。
    首先组件由一个定义连接细节的常数开始,在本例中针对SQL Server和p u b s数据库。

    然后创建第一个方法,向客户端Web页面提供一个记录集。这是一个标准的Visual Basic函数,返回一个标准的A D O R e c o RDS e t对象。


    这里有两个重要的地方需要注意。第一是把C u r s o r L o c a t i o n设为a d U s e C l i e n t,确保使用客户光标引擎。这对于断开连接的记录集是必要的。第二点需要注意是下面这一行代码:

    把记录集从服务器端“断开”,安全地将记录集返回给客户端。
    组件的第二个方法用我们对断开的记录集的修改来更新服务器。它接受一个记录集参数,重新连接到数据存储,然后发出U p d a t e B a t c h命令。这将所有批处理修改送到服务器。

    这就是这个组件的全部内容。很明显,我们把它简单化了,这样才能很快地显示其包含的内容,但实际上对于能在组件里放什么并没有任何限制。在本书第1 3章到第1 8章会看到更多的有关如何做以及为什么要这样做的例子。
10.3.2 DataSpace对象
    D a t a S p a c e对象是负责与服务器进行通讯的客户端对象。它的任务是提供一种方法,从客户端创建服务器端组件,同时允许在客户机和服务器之间传输数据。
    虽然听起来有些复杂,但实际上却是非常简单。在Web页面上创建一个D a t a S p a c e对象,再使用D a t a S p a c e对象创建服务器端组件。
    创建一个D a t a S p a c e对象有两种方法。第一种方法使用< OBJECT>标记:

    这与过去创建其他客户端RDS组件的方法几乎相同,唯一不同的就是类I D。
    第二种方法是使用脚本代码创建D a t a S p a c e对象。下面的代码显示了如何用J S c r i p t创建一个D a t a S p a c e对象。

    两种方法的主要区别在于:使用< OBJECT>标记时, D a t a S p a c e对象只在页面加载时才创建。使用脚本技术意味着当脚本运行时,就创建了D a t a S p a c e对象。如果想延迟对象创建以使页面加载得快一些,那么可以使用脚本技术。
    利用D a t a S p a c e对象创建服务器组件
    一旦创建了D a t a S p a c e对象,可以使用C r e a t e OBJECT方法创建服务器端对象。

    P ro g I D是希望创建的对象的I D,Connect i o n是Web服务器的U R L地址。例如,假设有一个提供p u b s数据库数据
的Visual Basic组件,如图1 0 - 1 2所示。

    在这里,P ro g I D应该是Wr o x P u b s . p u b s。下面以一个完整的例子详细说明。
    (1) 创建组件和获取数据
    假定p u b s类有两个方法, g e t A u t h o r s和s e t A u t h o r s,用于读取和更新a u t h o r s表。在创建组件之前,先创建一个RDS数据控件来存放和绑定数据。注意,这里没有连接的细节。

    然后可以使用以下客户端脚本代码创建服务器组件:

    这里创建了D a t a S p a c e对象的一个实例,然后使用C r e a t e OBJECT方法创建服务器端对象。这里,指定了对象和Web服务器的名称。在本例中将Web服务器的名字设为l o c a l h o s t,它应该是服务器的实际名称。这不是一个安全问题,因为用户正在与Web站点连接。
    现在,变量o b j P u b s是Wr o x P u b s . p u b s对象的一个实例,可以像使用其他对象一样调用其方法。

    调用g e t A u t h o r s方法返回一个断开连接的记录集。现在需要做的就是使用这个记录集,因此可以使用一个RDS数据控件(用< OBJECT >标记创建)来存放记录集并绑定数据。使用数据控件的SourceRecordset 属性来接收从组件中获取的记录集。

    在这种情形下,数据控件表现得就像自己在获取数据一样,唯一不同的是我们已经从组件中提供了数据。
    (2) 使用组件更新数据
    读者可能想知道使用服务器端组件时,如何更新数据?不能使用数据控件的S u b m i t C h a n g e s方法,因为数据控件没有连接的细节,因此不知道数据从哪里来。既然记录集是一个标准的断开连接的记录集,其数据又是由服务器组件提供的,那么组件似乎应该知道数据的来源?是的。因此需要把这个断开连接的记录集传给服务器组件,它会执行批处理更新。
    为了实现这一点,首先从数据控件中取出记录集,然后将其作为参数传给服务器对象的方法。

    实际上这相当简单。
10.3.3 使用服务器端组件的优点
    那么服务器端组件最大的特色是什么?看一下它的优点:
    ? 连接细节对用户不可见,为我们提供了一个更安全的系统。同时,组件也必须被注册,这又是一道附加的安全限制。
    ? 可以用任何兼容C O M的语言来创建组件。在例子中使用Visual Basic的原因是因为V B容易理解,但如果需要也可以使用V C + +或D e l p h i。这允许开发人员使用自己最熟悉的语言。
    ? 创建的组件并只不局限于返回和更新记录集。可构建大量封装的业务逻辑作为数据处理的一部分。
    ? 可以在s e t R e c o RDS e t方法中封装全部冲突处理的代码,而只返回错误的详细说明。这表明客户端脚本是规范的。同时,也意味着用户无法窃取你精心编写的代码。
    本书的下一节会详细介绍组件的优点。
10.3.4 注册服务器端组件
    在前面曾经说过,在Web浏览器中创建一个服务器组件之前必须修改注册表。为了让RDS能使用组件,必须将组件的P r o g I D添加到下面的注册表键中:

    警告:在编辑注册表时始终要很仔细。在修改之前备份注册表永远是明智的。
    运行r e g e d i t后,选择A D C L a u n c h键,然后从E d i t菜单中选择N e w,再选择K e y。现在为组件输入P r o g I D,例如图1 0 - 1 3所示。

    还应该考虑对注册表做一点修改以标明组件为“ safe for scripting”,这样在运行的时候,才会完全满足I E的要求。此时需要增加两个键,两个都需要组件的G U I D。

    实现的最好方法是使用Visual studio的Package and Deployment Wi z a r d创建一个Internet下载软件包(Internet Download Package)。如果选择了Safe for Initialization和Safe for Scripting这两个选项,那么当软件包安装到服务器时,将会更新注册表。如果确实需要得到组件的类I D,那么这个向导也能创建一个HTML文件,里面是一个带有组件类I D的<OBJECT>标记。
10.3.5 自定义处理器
    RDS数据控件是一个优秀的客户端工具,可在客户端处理大量的数据。大多数例子已经表明数据控件使用的是固定的数据集,比如a u t h o r s表。然而,动态数据绑定的例子表明了也可以让用户决定自己想要检索的数据。这可以通过创建按钮来实现,可为用户提供一个文本框来输入表名,甚至输入SQL查询字符串。
    当然,这增加了RDS数据控件的灵活性,但却是以牺牲安全性为代价的。如果用户对数据的使用范围不受限制,他们要么会觉得混乱,要么就想偷看那些保密的财务数据。因而我们需要的是一种灵活的,但又受一定限制的检索数据的方法。
    为了做到这一点可以使用一个处理器,可以在连接字符串或命令执行之前修改它们。
    处理器是一个包含四部分内容,分别由回车符分隔的文本文件:
    ? Connect节:确定连接字符串。
    ? SQL 节:确定SQL语句和命令。
    ? UserList节:确定用户。
    ? Logs 节:确定日志记录能力。
    该文本文件名缺省为M s d f m a p . i n i,安装在Wi n d o w s缺省目录中。
    1. Connect节
    Connect节允许覆盖连接字符串和访问细节,由下面两个条目之一标识:
    ? [connect default] 指出缺省的连接细节。
    ? [connect Connect i o n N a m e] 指出名为Connect i o n N a m e的连接的细节。
    在该节有两对名称/值,如表1 0 - 6所示。

    例如:

    这表明,如果数据控件的连接字符串为P u b s D a t a b a s e,用户将以G u e s t U s e r的身份登录到数据库,并且只有读的权限。因此,如果用户执行以下操作:


    这里的值覆盖了Connect节中的访问权限值。
    为了正确使用U s e r L i s t节,服务器必须能够验证用户,因此这取决于服务器上的验证规则。例如,如果使用匿名访问,那么所有用户都会以Web站点中I I S管理属性所指定的缺省用户身份连接到服务器。
    4. Logs节
    Logs节允许指定一个写入错误的文件名由[Logs]标识。日志记录应用于所有连接。如果此日志文件不存在则会创建一个新的日志文件。

    6. 使用自定义处理器
    可以使用RDS数据控件的Handler属性来指定处理器,并给指定处理器的名字。缺省的处理器是M S D F M A P. Handler,它是RDS服务器端部分使用的一个组件。也可以编写自己的自定义处理器(标准的C O M组件),如果这样做,应该参考RDS的文档。


分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间

上一篇管理错误

下一篇远程数据服务

点击: