选择显示字体大小

用asp和vbscript上载文件(一)

    
  青苹果电脑工作室
    从浏览器上载文件是从客户机向服务器传递文件的一个简易方法。从第三代浏览.netscape和 microsoft起,多数浏览器都可以向服务器上载文件,而不需要向用户提供特殊的访问方式或软件。
  
  一些asp组件是为文件上载而设计的,例如:
  posting acceptor
  ( microsoft siteserver的一部分),
  aspsmartupload(advantys),
  aspupload (persistssoftware),
  sa-fileupsoftware artisants)
  
    本文的开始将告诉你关于创建这类组件的信息,而这些组件通常使用vb、c++或java
  
    这些组件的问题在于它们是第三方产品而非标准asp的一部分。作为第三方组件,必须在服务器上进行安装。这就意味着必须在服务器上复制dll并注册。大多数的主机系统不允许在他们的服务器上进行这样的设置,因为有可能发生配置问题(尤其是虚拟主机)。第二个缺点是它们大部分不是免费的,不提供源代码,也就不能根据需要进行定制。
  
    因此我需要编写vbscript代码来解决文件上载的问题。这不是一个必然的选择,因为vbscript是一种脚本语言,只能使用variants数据类型,并且不能提供许多管理二进制数据和字节数组的内置函数。
  
    要理解上载的过程,首先要知道数据用http协议从浏览器发送到服务器的方式。这就意味着要理解“ multipart/form-data” (多部分/格式-数据)的表单提交。
  
  上载表单
  
    通常情况下,使用html表单从浏览器向服务器传递数据。这个表单中可能包含文本域、检验框、按钮以及上载文件的文件类型控制。使用者用自己的数据填充并将这个表提交给服务器
  
    表单元素中的 enctype 属性规定了传递给服务器的表数据集编码的内容类型。enctype 属性的默认值是“application/x-www-form-urlencoded”,但当向服务器传送大量文本、包含非ascii字符或二进制数的数据时,这个默认类型就不能胜任了。这时,文件上载提交表单时应使用“multipart/form-data”内容类型。
  
    一个“multipart/form-data”信息包含一系列部件,每个部件都可能包含:
  一个content-disposition(内容-处理)头,其值为"form-data" ;一个规定控制名的name(名称)属性。
  
    对于一个文件类型控制,一个部件可能包含更多信息:
  在客户机上规定原始路径和文件名的filename(文件名)属性;所发送的二进制数据控制的content-type (内容-类型)头。
  
    在这些头的后面跟随着控制的二进制或文本内容。
  
    以下例子说明“multipart/form-data”的编码,客户机的浏览器应有这个表单:
  
  如果这个表单被提交,在服务器上可读到这些请求:
  
  -----------------------------7cf87224d2020a
  content-disposition: form-data; name="email"
  phcollignon@email.com
  -----------------------------7cf87224d2020a
  content-disposition: form-data; name="blob"; filename="c:\image.gif"
  content-type: image/pjpeg
  
  -----------------------------7cf87224d2020a
  content-disposition: form-data; name="enter"
  submit query
  -----------------------------7cf87224d2020a--
  
    当那个内容作为响应被传送回客户机时就会被显示出来。应该用request.binaryread 和response.binarywrite 方法读和写二进制数据。
  
  〈%
  response.binarywrite(request.binaryread(request.totalbytes))
  %〉
  
  可以看到响应的各部分用分界线来划分:
  -----------------------------7cf87224d2020a
  最后一个分界线后面跟随的是’ -- ’ 。
  
    每一个控制都有一个content-disposition 。name属性识别由html表发送的控制(email、blob和enter)。 对于一个文件类型控制(blob),
  文件名也是content-disposition 头的一部分,content-type 头给出二进制 数据的内容类型。
  
  上载脚本
  
    上面所有内容都必须经过分解。在vb 或 c++中, 这非常明显,因为为此提供了许多对象和方法。在vbscript 中,必须使用语言所提供的一些函数,并要解决vbscript中使用的双字节编码的变量字符串的问题。
  
  vbscript函数
  
    原始数据是二进制格式,所以必须使用专为管理二进制数据而设计的vbscript函数。因为我们将原始数据作为一个字节的字符串来考虑, 所以 midb、instrb 和 lenb 函数就有用了。 但是要避免vbscript的classic字符串,因为它们是双字节编码的字符串,不适宜分解成单字节。
  
    这些是vbscript函数中仅有的用来分解字节的函数。还需要一个方法,从被分解的数据中得到双字节编码的字符串,这样就可以使用vbscript编码中的字符串了。为了在instrb中把字符串作为一个自变量使用,还需要一个函数,把双字节字符串转换成单字节字符串。
  
    为了我写了两个函数,getstring() 和 getbytestring(),稍后再对此进行解释。
  
  结构
  
    分解的数据被存储在vbscript dictionary 对象中。 dictionary 对象是hash 表对象,它存储(key, item)对。它是vbscriptasp2.0的一部分。
  
    定义第一个dictionary 对象 " uploadrequest " 。这个对象包含由上载表提交的所有控制。key是控制的名字,item则是对象中所包含的控制的信息:
  "controlname1", dictionary control1
  "controlname2", dictionary control2
  
    代表一个控制的dictionary 对象包含着下面的(key, item) 对:
  "value", string or binary content
  "filename", name of uploaded file
  "contenttype", contenttype of uploaded file
  
    把这些结合起来,就有以下例子:
  
  uploadrequest : "email", uploadcontrol 1 : "value", phcollignon@email.com
  "blob" , uploadcontrol 2 : "filename", c:/image/file.gif "contenttype" :
  image/gif "value" : gif89ai?
  这个对象对于以后存取和使用数据非常有用。
  
  分解
  
    这里是分解、读和记录上载控制的代码。这个过程用"builduploadrequest"程序来完成,这个程序只有一个自变量,就是原始二进制数据requestbin。
  
  sub builduploadrequest(requestbin)
  
    首先要找到分界线,通过分界线可以知道控制循环何时结束。
  
  ’get the boundary posbeg = 1 posend = instrb(posbeg,requestbin,getbytestring(chr(13)))
  boundary = midb(requestbin,posbeg,posend-posbeg) boundarypos = instrb(1,requestbin,boundary)
  
    有一个问题是instrb需要单字节字符串作为自变量。为此写了一个函数:getbytestring(string) ,此方法可以把vbscript的双字节字符串转换成单字节字符串。在代码解释的最后再描述这个函数。
  
  在找到结束分界线之前进行下列循环:
  ’get all data inside the boundaries
  do until (boundarypos=instrb(requestbin,boundary & getbytestring("--")))
  
    循环中的每一步都处理一个控制。有关这一控制的所有数据都保存在dictionary对象中。每一个循环创建一个新的dictionary对象uploadcontrol。
  
  ’members variable of objects are put in a dictionary object dim uploadcontrol
  set uploadcontrol = createobject("scripting.dictionary")
  
    首先从" content-disposition " 头中找到控制的名字。名字的结尾用"字符或chr(34)划分。
  ’get an object name pos = instrb(boundarypos,requestbin,getbytestring("content-disposition"))
  pos = instrb(pos,requestbin,getbytestring("name=")) posbeg = pos+6 posend
  = instrb(posbeg,requestbin,getbytestring(chr(34))) name = getstring(midb(requestbin,posbeg,posend-posbeg))
  
    现在测试控制是文件类控制还是文本类控制。如果是文本类控制,除了它的名字以外没有其它任何数据。 如果是文件类控制,就会得到一些额外信息,如文件名和content-type。
  
  posfile=instrb(boundarypos,requestbin,getbytestring("filename=")) posbound
  = instrb(posend,requestbin,boundary) ’test if object is of file type if
  posfile〈〉0 and (posfile〈posbound)
  
    then 如果是控制是文件类控制,就将路径和文件名进行分解,并将他们填加到控制的dictionary 对象中。分解后的文件名是一个单字节字符串,要将它转换成双字节字符串才能作为variant字符串变量使用。这通过最后定义的getstring()方法来实现:
  
  ’get filename, content-type and content of file posbeg = posfile + 10 posend
  = instrb(posbeg,requestbin,getbytestring(chr(34))) filename = getstring(midb(requestbin,posbeg,posend-posbeg))
  ’add filename to dictionary object uploadcontrol.add "filename", filename
  pos = instrb(posend,requestbin,getbytestring("content-type:")) posbeg =
  pos+14 posend = instrb(posbeg,requestbin,getbytestring(chr(13))) ’add content-type
  to dictionary object contenttype = getstring(midb(requestbin,posbeg,posend-posbeg))
  
    uploadcontrol.add "contenttype",contenttype 现在就可以得到文件的核心内容了。这个内容不需要转换,因为它是二进制的。可以将它存入一个文件系统或作为一个二进制长对象(blob)放入数据库中。
  
  ’get content of object posbeg = posend+4 posend = instrb(posbeg,requestbin,boundary)-2
  value = midb(requestbin,posbeg,posend-posbeg)
  
    else 如果是文本类控制,除了内容以外就没有其它数据需要分解。内容要转换成为双字节字符串,以便将来用 在vbscript代码中。
  
  ’get content of object pos = instrb(pos,requestbin,getbytestring(chr(13)))
  posbeg = pos+4 posend = instrb(posbeg,requestbin,boundary)-2 value = getstring(midb(requestbin,posbeg,posend-posbeg))
  end if
  
    将内容加入dictionary对象中。将key设置成 " value ",那么item 就是内容。根据控制类型的不同,内容可以是字符串或二进制数据。
  
  ’add content to dictionary object
  uploadcontrol.add "value" , value
  
    最后将控制的dictionary 对象加入一个全程dictionary 对象中。使用的key 是控制的名字。item 是刚刚创建的dictionary对象,名为uploadcontrol。
  
  ’add dictionary object to main dictionary uploadrequest.add name, uploadcontrol
  ’loop to next object boundarypos=instrb(boundarypos+lenb(boundary),requestbin,boundary)
  loop end sub
  
  字节-字符串转换函数
  
  下面是将双字节字符串转换成单字节字符串的函数。
  
  ’byte string to string conversion function getstring(stringbin) getstring
  ="" for intcount = 1 to lenb(stringbin) getstring = getstring & chr(ascb(midb(stringbin,intcount,1)))
  next end function 下面是将字符串转换成单字节字符串的函数,它用来格式化instrb函数的自变量。
  
  ’string to byte string conversion function getbytestring(stringstr) for
  i = 1 to len(stringstr) char = mid(stringstr,i,1) getbytestring = getbytestring
  & chrb(ascb(char)) next end function
  
    


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons