欢迎光临
我们一直在努力

用ASP和VBScript上载文件(一)-ASP教程,ASP应用

建站超值云服务器,限时71元/月

从浏览器上载文件是从客户机向服务器传递文件的一个简易方法。从第三代浏览器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)对。它是vbscript和asp2.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

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 用ASP和VBScript上载文件(一)-ASP教程,ASP应用
分享到: 更多 (0)