一、上传网页

   

  上传页面代码:

<form   action="upload.asp"   method="post"   enctype="multipart/form-data"   name="form1">

<input   type="file"   name="file">

<input   type="submit"   name="Submit"   value="提交">

</form>

  说明:

  ①在form中必须使用属性“enctype="multipart/form-data"”,一旦使用该属性,表单的值就不能使用Request.Form或Request.QueryString来接收表单组件的内容了。因为表单会以二进制流的形式提交,而不是文本。如果需要获取上传的文件,就必须使用Request对象的BinaryRead方法来读取。

  ②必须使用“<input   type="file"   name="file">”。

二、二进制流文件结构介绍

  要编写无组件上传文件程序,必须要搞清楚经过表单发送过来的文件的结构。

  1)第一部分(起始标志)
  -----------------------------7dc18645076a
  2)第二部分(文件说明)
    Content-Disposition: form-data; name="file1"; filename="E:\U盘备份(09年上)\08春期理工责任教师表.doc" Content-Type: application/msword
  在此,我们可以获得上传文件的文件名称及绝对路径,也可以获得文件类型。这些信息是正确保存文件所不可缺少的。
  3)第三部分(文件内容)
  即文件的二进制内容,略。
  4)第四部分(结束标志)
    -----------------------------7dc18645076a

说明:而且每一个部分都是用回车换行符号来进行分隔的。第一部分和第四部分标志每次上传都是不一样的,起到了分隔符的作用。(多文件上传的时候很有作用的)。在asp中可以通过Request.ServerVariables("HTTP_CONTENT_TYPE")来获取,例如上例中HTTP_CONTENT_TYPE内容为:"multipart/form-data; boundary=-----------------------------7dc18645076a",有了这个,我们不仅可以判断客户端的form中有无使用enctype="multipart/form-data"(如果没有使用,那么下面就没必要执行啦),还可以获取边界值boundary=-----------------------------7dc18645076a"。(注意:这里获取的边界值比上面的边界值开头要少"--",最好补充上。)

  例:以上传一个文本文件为例。 

  显示文件结构的程序:

  <%
   Dim filesize, filedata, PostData
   filesize = Request.TotalBytes
   filedata = Request.BinaryRead(filesize)
   PostData = BinaryToString(filedata,filesize)
   Response.Write "<pre>" & PostData & "</pre>" '使用pre,原样输出格式
   ' 借助RecordSet将二进制流转化成文本
   Function BinaryToString(biData,Size) 
     Const adLongVarChar = 201
     Set RS = createObject("ADODB.Recordset")
     RS.Fields.Append "mBinary", adLongVarChar, Size
     RS.Open
     RS.AddNew
     RS("mBinary").AppendChunk(biData)
     RS.update
     BinaryToString = RS("mBinary").Value
     RS.Close
   End Function 
  %>

  显示结果:    

-----------------------------7dc37a225076a
Content-Disposition: form-data; name="file"; filename="E:\U盘备份(09年上)\C++语言程序设计.txt"
Content-Type: text/plain《C++语言程序设计》是成人专科中计算机信息管理和机械制造与自动化等专业的一门选修课。 开设本课程的目的,是使学生掌握一门高级程序设计语言,了解面向对象程序设计的基本概念与方法,进而学会利用C++语言解决一般应用问题,并为后续的专业课程奠定程序设计基础。
-----------------------------7dc37a225076a
Content-Disposition: form-data; name="Submit"
提交
-----------------------------7dc37a225076a--

三、获取上传文件名

  了解了经过表单发送过来的文件的结构后,首先需要从第二部分数据的"filename"中获得文件名称,然后需要正确定位文件的起始位置,最后利用ASP技术将二进制文件用本来的文件名保存即可。
  ⑴预备函数(将二进制串转化成字符串)  
  上传文件的内容不需要经过二进制向字符串的转换过程,直接保存就可。但是,若需提取文本框内容或文件的名称,就必须进行转换。因此,需要编写一个通用的,并且适用于汉字的转换函数。以下是该函数代码:
  Function BtoS (bstr)  
    If not IsNull(bstr) Then  
        for i = 0 to lenb(bstr) - 1  
           bchr = midb(bstr,i+1,1)  
           If ascb(bchr)〉127 Then  
              temp = temp&chr(ascw(midb(bstr, i+2, 1)&bchr))  
              i = i+1  
           Else  
              temp = temp&chr(ascb(bchr))  
           End If  
        next  
     End If  
     BtoS = temp  
  End Function

  ⑵ 获得文件名内容

  filesize = Request.TotalBytes             'filesize是上传文件的大小
  filedata = Request.BinaryRead(filesize)   'filedata是上传文件的二进制数据
  newline=chrB(13)&chrB(10)                 'newline表示二进制的回车符
  delimiter=leftB(filedata,clng(instrb(filedata,newline))-1)         'delimiter是分割符
  n1=clng(instrb(filedata,newline))+2         '获取第二部分的开始位置n1
  n2=clng(instrb(n1,filedata,newline))        '获取第二部分中上传文件名行的结束位置n2
  filenames=BtoS(midB(filedata,n1,n2-n1))     '获取第二部分中上传文件名行的文本内容
  n3=instrrev(filenames,"\")                  '获取上传文件名的开始位置
  filename=mid(filenames,n3+1,len(filenames)-n3-1)  '获取上传文件名(不含路径)
四、获取上传文件内容的起始位置
  上传文件内容的开始位置是在第四个回车符之后,而结束位置在第二个分隔符"delimiter"开始位置之前,但上传文件内容和分隔符之间用回车符分隔,所以上传文件内容的最后一个字符应该是第二个分隔符"delimiter"的开始位置-3。
  程序代码如下:
  beginpos=clng(instrb(n2+1,filedata,newline))  '获取第三个回车符的第一个字符位置
  beginpos=clng(instrb(beginpos+1,filedata,newline))+1   '获取文件内容第一个字符之前的位置
    endpos=clng(instrb(lenb(delimiter),filedata,delimiter))-3  '获取文件内容中最后一个字符的位置
五、文件上传

  上传文件必须要创建两个(或多个)STREAM对象,其中一个为源数据流,即接收初始的二进制数据;另一个为目的数据流,即接收来自经源数据流处理后的数据,并最终保存为所需的文件。

  程序代码如下:

set str_c=server.CreateObject("ADODB.Stream")   '创建一个ADODB.Stream对象,str_c为源数据流  
     str_c.Mode=3   '设置打开模式,3为可读可写  
     str_c.Type=1   '设置数据类型,1为二进制数据  
     str_c.Open     '打开对像
     set  desc=server.CreateObject("ADODB.Stream")   '创建一个ADODB.Stream对象,desc为目标数据流  
     desc.Mode=3    
     Desc.Type=1    
     desc.Open  
     SaveFile = Server.MapPath("upload\" & filename)     '获取保存文件路径及文件名 
     str_c.Write filedata                '将指定的二进制数据流装入对像str_c中  
     str_c.position=beginpos             'position指出文件的开始位置  
     str_c.copyto  desc,endpos-beginpos  'endpos-beginpos是文件的长度
     desc.SaveToFile SaveFile,2          '以SaveFile指定的路径及名称保存文件   
     '完成后,应关闭并释放STEAM对象
     Desc.Close    
     Set desc=nothing  
     str_c.Close    
     Set str_c=nothing  
     Response.write "文件上传成功!"

六、总结

  上述分析用asp上传一个文件的基本原理和过程,实际编程中必须对上述程序进行修改和完善。比如,如何限制上传文件类型?如何限制上传文件的大小?检查上传文件夹是否存在(不存在则创建文件夹)?检查上传文件是否存在(不存在,则重命名上传文件)?如何跟踪文件上传进度?上传文件过程中出现错误如何处理?等等这些问题都需要编程解决。

  下面给出上述程序的完整代码(文件名:upload.asp)

<%
   SavePath = "upload"          '保存路径
   filesize = Request.TotalBytes             'filesize是上传文件的大小
   filedata = Request.BinaryRead(filesize)   'filedata是上传文件的二进制数据
   newline=chrB(13)&chrB(10)                 'newline表示二进制的回车符
   delimiter=leftB(filedata,clng(instrb(filedata,newline))-1)         'delimiter是分隔符
   n1=clng(instrb(filedata,newline))+2         '获取第二部分的开始位置n1
   n2=clng(instrb(n1,filedata,newline))        '获取第二部分中上传文件名行的结束位置n2,即第二个回车符的第一个字符
   filenames=BtoS(midB(filedata,n1,n2-n1))     '获取第二部分中上传文件名行的文本内容
   n3=instrrev(filenames,"\")                  '获取上传文件名的开始位置
   filename=mid(filenames,n3+1,len(filenames)-n3-1)  '获取上传文件名(不含路径)

'下面开始取得文件内容开始的位置,第四个回车符后的第一个字符 
   beginpos=clng(instrb(n2+1,filedata,newline))  '获取第三个回车符的第一个字符位置
   beginpos=clng(instrb(beginpos+1,filedata,newline))+1   '获取文件内容第一个字符之前的位置
   
   '取得文件内容结束的位置,第二个分隔符"delimiter"开始的前一个二进制字符  
   endpos=clng(instrb(lenb(delimiter),filedata,delimiter))-3  '获取文件内容中最后一个字符的位置

set str_c=server.CreateObject("ADODB.Stream")   '创建一个ADODB.Stream对象,str_c为源数据流  
   str_c.Mode=3   '设置打开模式,3为可读可写  
   str_c.Type=1   '设置数据类型,1为二进制数据  
   str_c.Open     '打开对像
   set  desc=server.CreateObject("ADODB.Stream")   '创建一个ADODB.Stream对象,desc为目标数据流  
   desc.Mode=3    
   Desc.Type=1    
   desc.Open  
   SaveFile = Server.MapPath(SavePath & "\" & filename)     '获取保存文件路径及文件名 
   str_c.Write filedata                '将指定的二进制数据流装入对像str_c中  
   str_c.position=beginpos             'position指出文件的开始位置  
   str_c.copyto  desc,endpos-beginpos  'endpos-beginpos是文件的长度
   desc.SaveToFile SaveFile,2          '以SaveFile指定的路径及名称保存文件  
 
   '完成后,应关闭并释放STEAM对象
   Desc.Close    
   Set desc=nothing  
   str_c.Close    
   Set str_c=nothing  
   Response.write "文件上传成功!"
   '将二进制转换成文本
   Function BtoS (bstr) 
     If not IsNull(bstr) Then 
         for i = 0 to lenb(bstr) - 1 
            bchr = midb(bstr,i+1,1) 
            If ascb(bchr)>127 Then 
               temp = temp&chr(ascw(midb(bstr, i+2, 1)&bchr)) 
               i = i+1 
            Else 
               temp = temp&chr(ascb(bchr)) 
            End If 
         next 
      End If 
      BtoS = temp 
   End Function

%>

asp实现无组件上传文件原理相关推荐

  1. ASP.NET 无刷新上传文件

    这些天一直在做一个无刷新的文件上传功能,现在也总算是做好.可以说是是几经波折吧,开始一直想用AJAX的思路去实现,没想到费了很多时间最后还是徒劳!用ADODB.STREAM 应该也是可以把表单的文件P ...

  2. html5无组件上传,ASP上传漏洞 无组件上传图片文件(转载)

    对于上传漏洞的查找,仍是从源文件入手,目标有两个,一个是FilePath(文件路径),另一个则是FileName(文件名称). 一.FilePath 说到FilePath,有些朋友可能感到陌生,但要提 ...

  3. 6行代码实现ASP无组件上传

    目前有很多无组件上传类,我大概看了一下,大多写的相当复杂,有的居然还只能传文本,最关键的是没有10行代码以下的:),我花了一个晚上时间研究了一下ADODB.Stream,并且用了6行代码实现了无组件上 ...

  4. ASP实例:6行代码实现无组件上传

    ASP实例:6行代码实现无组件上传 目前有很多无组件上传类,我大概看了一下,大多写的相当复杂,有的居然还只能传文本 最关键的是没有10行代码以下的 :) 我花了一个晚上时间研究了一下ADODB.Str ...

  5. Asp无组件上传进度条解决方案

    http://webuc.net/dotey/archive/2004/07/22/1334.aspx 我还是一点一点用一个实例来说明的吧,客户端HTML如下.要浏览上传附件,我们通过<inpu ...

  6. 在本地测试无组件上传类上传大文件可以,在服务器上就不行,仿163网盘无刷新文件上传系统...

    回复  引用  查看     2008-10-20 11:03 | fkeuem 真的很不错.谢谢. 回复  引用  查看     2008-10-20 11:20 | PuserChen 下载了,学 ...

  7. 关于ASP无组件上传在2003下出错

    关于ASP无组件上传在2003下出错.. 问题描述: asp无组件上传程序无法上传较大的文件"Request 对象 错误 ASP 0104 : 80004005",(大概大于100 ...

  8. 最快的ASP无组件上传类(4M只需10秒)0.96版

    <% '---------------------------------------------------------------------- '转发时请保留此声明信息,这段声明不并会影响 ...

  9. asp无组件上传类的应用实例/化境HTTP上传程序

    原版 upload_5xsoft.inc 文件内容 <SCRIPT RUNAT=SERVER LANGUAGE=VBSCRIPT> dim Data_5xsoft Class upload ...

最新文章

  1. 读农民工兄弟学C#文章后的感觉
  2. 平均数、中位数和众数及它们之间的关系
  3. session与cookie的区别
  4. Linux查看和剔除当前登录用户详细教程
  5. 现代游戏中的UX趋势
  6. git ssh拉取代码_阿里云搭建git服务器
  7. dtc mysql_DTCC归来-高可用可扩展数据库架构探讨
  8. oracle快速创建可用用户
  9. Understand Rails Authenticity Token
  10. visio图片插入word,Acrobat导出pdf格式错乱
  11. 【技术框架汇总】_开发平台_前端框架_手机端框架_测试工具_数据库中间件_监控工具_框架_汇总
  12. 非常赞的文章!告诉你一个你知其然却不知其所以然的硅谷
  13. 安川机器人如何注释化指令_安川机器人命令介绍
  14. Android使用蓝牙录音和播放
  15. 慧都与数据库厂商Devart进一步提升合作层次
  16. 博士预答辩之后关于中文论文踩坑心得
  17. 学iOS开发需要什么样的基础?
  18. 数字化会议管理系统,实现会议全流程管理
  19. 如何关闭华为手机连接电脑自动弹出cd驱动器和类似文件管理文件夹
  20. 部署Guacamole远程控制桌面

热门文章

  1. mysql rds 迁移_数据库迁移:如何将数据库从本地MySQL迁移到服务器RDS上?
  2. 距离北京奥运还有359天,发布WPF版本的北京2008标志(下)
  3. 4. Spring Cloud Gateway自定义Filter
  4. ARP协议的小小了解
  5. Google DeepMind的新论文: Spatial Transformer Networks
  6. 三大运营商个人轨迹证明方法
  7. CAD插件学习系列教程(六) 文字自动避让工具
  8. Voxel-RCNN
  9. 【敏捷办公学习必备软件推荐】
  10. k、K、kb、kB、Kb、KB、GB、MB之间的关系