Web文件上传原理

采用WEB技术实现B/S(浏览器/服务器)结构的管理系统是办公自动化的发展趋势。基于WEB技术的管理系统,由于开发周期短;与用户平台无关;易于实现交互式应用;能对信息进行快速、高效的收集、处理和发布,近几年来得到了迅速发展。而ASP技术由于其开发效率高、交互性好,安全性强等特点,逐渐成为开发管理系统的首选工具。

  许多基于WEB的应用都涉及文件上传操作。常见的文件上传技术有:基于HTTP协议的;基于VB(或DELPHI等编程语言)开发的文件上传组件的;基于数据库技术的等等。这些方法一般都需要编程者能同时掌握WEB技术、数据库技术或CGI技术或组件技术,对编程者的要求较高。而本文将介绍的利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可,大大降低了编程难度。

  几种文件上传技术的比较

  1、基于HTTP协议

  该方法需要编程者利用第三方软件,如DELPHI、VB等,在应用程序中先进行HTTP协议编程,然后将待上传文件内容按HTTP协议的格式打包,最后向WEB服务器发送上传的请求报文,从而实现文件的上传。因为DELPHI和VB不能编写完整的WEB网络程序,只能编写WEB小应用程序,因此,该方法只用于功能受限的网络应用。

  2、基于VB(或DELPHI等)开发的文件上传组件

  该方法利用VB(或DELPHI等编程语言)开发ASP服务器组件,实现特定的文件上传服务。它首先利用ASP表单功能将文件(二进制格式)从用户端上传到服务器端,然后使用VB开发的组件,对二进制文件进行处理,成为可以正常读写的文件。该方法要求编程者不仅掌握ASP语言,而且还能利用VB等第三方语言进行组件编程,增加了开发的难度。

  3、基于数据库技术

  该方法和上个方法有类似之处。不同的地方在于对上传的二进制文件的处理上。它使用数据库来保存二进制文件。无论是小型数据库还是大型数据库都提供了存储二进制数据的数据类型,只要以Append Chunk方式将数据存入相应的字段就可以了。该方法虽然简单可行,但是因为每次上传的文件大小都是不一样的,因此,会对数据库的空间造成很大的浪费,降低了数据的访问速度;并且使得文件只能在数据库环境下进行访问,造成了很大的不便。

  实例分析

  但是,利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可,

  大大降低了编程难度。下面我们将通过一个实例来介绍如何使用该方法。

  1、文件上传表单

  首先需要编写一个能提供文件上传功能的表单,程序如下所示:

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

上传文件:<Input type=file name=file1><br>

<input type=submit name=upload value="上传">

</form>

  其中,enctype参数用来设置表单的MIME编码方式,在进行文件(或同时包含文本框)上传时,必须将其属性设置为"multipart/form-data";upload.asp是服务器端对接收到的二进制文件流进行处理的ASP程序,在本文的后面将陆续介绍其内容。

  2、上传文件格式分析

  在处理文件之前,我们要先了解上传的文件的具体格式,通过编写下面一段简单的ASP程序就可以查看其二进制代码:

<%

filesize=Request.TotalBytes ‘获得上传文件的大小

filedata=Request.BinaryRead(filesize) ‘获得上传文件的二进制数据

Response.BinaryWrite filedata ‘在浏览器上显示二进制数据

%>

  分析浏览器上显示的上传文件的二进制代码,发现代码包括四个部分(若同时上传多个文件或文本框,则代码按上传的先后次序排列,格式相同),每一部分的内容是用回车换行符号来进行分隔的:

  1)第一部分(起始标志)

  -----------------------------7d329631b04d4

  2)第二部分(文件说明)

Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings\Administrator\My Documents\Invitation.doc" Content-Type: application/msword

  在此,我们可以获得上传文件的文件名称及绝对路径,也可以获得文件类型。这些信息是正确保存文件所不可缺少的。

  

  3)第三部分(文件内容)

  即文件的二进制内容,略。

  4)第四部分(结束标志)

-----------------------------7d329631b04d4

  结合第一部分和第四部分的内容来看,"-----------------------------7d329631b04d4"(每次上传,数值都不一样)起到了分割符的作用,它标志着一段数据(当有多个上传内容时)的开始和结束。从保存文件所需要的信息来讲,我们首先需要从第二部分数据的"filename"中获得文件名称,然后需要正确定位文件的起始位置,最后利用ASP技术将二进制文件用本来的文件名保存即可。若同时上传多个内容(如多个文本框和文件),也是按同样的方法处理,每部分的内容都包含在分割符之中,只是文本框和文件的表现形式稍有不同,这可以通过具体分析其二进制代码来了解。

  3、利用ASP技术实现文件存储

  上传文件代码的处理

  1) 获得分割符代码

  从上面的分析我们已经知道,分割符起到了分割多个数据段(包括文本框和各种类型的文件)的重要作用。前面已经分析过,分割符出现在第一个回车换行符号前。因此,通过下面这段程序就可获得分割符代码:

<%

newline=chrB(13) & chrB(10) ‘newline表示二进制的回车符

filesize=Request.TotalBytes ‘filesize是上传文件的大小

filedata=Request.BinaryRead(filesize) ‘filedata是上传文件的二进制数据

divider=leftB(filedata,clng(instrb(filedata,newline))-1) ‘divider是分割符

%>

  注:因为这里处理的都是二进制字节码,因此,所有的函数都是使用它的二进制版本,加了"b "。

  2) 获得文件(或文本框)内容

  (1) 预备函数(将二进制串转化成字符串)

  上传文件的内容不需要经过二进制向字符串的转换过程,直接保存就可。但是,若需提取文本框内容或文件的名称,就必须进行转换。因此,需要编写一个通用的,并且适用于汉字的转换函数。以下是该函数代码:

Function BtoS (bstr)

If not Is Null (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

  (2) 获得文件(或文本框)内容

  在实际的WEB应用中,上传操作可能涉及多项内容,如多个文本框、多个文件等等。文件和文本框很好区分,文件的数据中包含了"filename="字串。因此,我们写了如下的通用函数,既可用于提取文件内容,又可提取文本框内容(需进行二进制转换):

Function getdata(byval data, byval divider, final) ‘data表示二进制串;divider表示分割符;final表示数据的结束位置

filename=chrb(102)&chrb(105)&chrb(108)&chrb(101)&chrb(110)&chrb(97)&chrb(109)&chrb(101)&chrb(61)&chrb(34) ‘字符串"filename"的二进制表示

bncrlf=chrb(13)&chrb(10) ‘二进制的回车符

startpos = instrb(data,divider)+lenb(divider)+lenb(bncrlf) ‘ 开始位置

endpos = instrb(startpos,data, divider)-lenb(bncrlf) ‘结束位置

part1 = midb(data, startpos, endpos-startpos) ‘两个分割符之间的内容

firstline = midb(part1, 1, instrb(part1, bncrlf)-1) ‘ 内容之前的说明段

If (instrb(firstline,filename)=0) Then ‘若为文本框,获得文本框字符串内容

stemp=midb(part1,instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf),lenb(part1)-instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf))

getdata=BtoS(stemp)

Else ‘若为文件,获得文件二进制内容

Getdata=midb (part1, instrb (part1, bncrlf&bncrlf)+lenb (bncrlf&bncrlf), lenb (part1)

-instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf))

End If

Final=endpos

End function

  在程序中直接调用该函数就可获得所需文件(或文本框)内容,如下所示:

<%

C (data, divider, position)

%>

  3) 获得文件名称

  前面已经分析过了,上传文件数据流的"filename="字段里包含了文件的名称和绝对路 径。一般来说,我们只需提取出路径中的文件名即可,以下是程序代码:

<%

namepos=instrrev(B2S(firstline),chr(92)) ‘firstline即上面获得的说明部分数据,chr(92)

表示"/"

filename=midb(firstline,namepos+1,lenb(firstline)-namepos-1) ‘获得文件名称

%>

  利用ASP直接实现文件上传功能

  传统的ASP程序员只能利用FILESYSTEMOBJECT对象对文本文件(.txt)进行移动、复制、删除等操作,若需处理二进制对象,则不得不采用本文前面介绍的那些方法来实现。但是,现在ASP中的ADO.STREAM对象可以同时操作文本对象和二进制对象(可以在http://www.microsoft.com/data下载),利用它就可以在ASP中直接实现文件上传功能。下面,我们就介绍其实现过程。

  1)打开STREAM对象

  对于SREAM对象而言,若要进行文件的保存,则必须是将该对象的全部内容进行保存。因此,我们必须要创建两个(或多个)STREAM对象,其中一个为源数据流,即接收初始的二进制数据;另一个为目的数据流,即接收来自经源数据流处理后的数据,并最终保存为所需的文件。

<%

set str=server.CreateObject("ADODB.Stream") ‘str为源数据流

str.Mode=3 ‘设置打开模式,3为可读可写

str.Type=1 ‘设置数据类型,1为二进制数据

str.Open

set desc=server.CreateObject("ADODB.Stream") ‘desc为目标数据流

desc.Mode=3

Desc.Type=1

desc.Open

%>

  2)STEAM对象间内容的复制

  在该部分,必须在源数据流中定位文件开始的位置,并且求出文件内容的长度,才能将文件正确的复制到目的数据流中,并且保存文件,程序代码如下:

<%

formdata=Request.BinaryRead(Request.TotalBytes) ‘formdata为上传的所有内容

str.Write formdata ‘ 赋值源数据流

str.position=count-lenb(result)-2 ‘position指出文件的开始位置

str.copyto desc, lenb(filecotent) ‘lenb(filecontent)表示文件的长度

desc.SaveToFile fullpath,2 ‘以fullpath指定的路径及名称保存文件

%>

  3)关闭STEAM对象

  编程完成后,应关闭并释放STEAM对象,如下所示:

<%

Desc. Close

Set desc=nothing

Str. Close

Set STR=nothing

%>

Web文件上传原理

时间: 2024-12-18 08:25:53

Web文件上传原理的相关文章

[转]文件上传原理:Web上传文件的原理及实现

现在有很多Web程序都有上传功能,实现上传功能的组件或框架也很多,如基于java的CommonsFileUpload.还有Struts1.x和Struts2中带的上传文件功能(实际上,Struts2在底层也使用了CommonsFileUpload).在asp.net中也有相应的上传文件的控件. 虽然现在有很多上传组件可以利用,但是了解Web上传文件的原理,对于处理突然出现的问题会有很大的帮助,下面就来讲一下通过浏览器上传文件的基本原理.在了解了原理之后,就可以非常容易地自制满足自身需要的上传组件

php文件上传原理详解(含源码)

1.文件上传原理 将客户端的文件上传到服务器,再将服务器的临时文件上传到指定目录 2.客户端配置 提交表单 表单的发送方式为post 添加enctype="multipart/form-data" 3.服务器端配置 file_uploads = On,支持HTTP上传 uoload_tmp_dir = ,临时文件保存目录 upload_max_filesize = 2M,允许上传文件的最大值 max_file_uploads = 20 ,允许一次上传到的最大文件数 post_max_s

PHP单文件上传原理及上传函数的封装

<?php //单文件上传函数的封装 //文件上传原理:将客户端的文件上传到服务器端,再将服务器端的临时文件移动到指定目录即可. //文件的方向:客户端-->服务器(临时文件)-->指定目录,当文件进入服务器时它就是临时文件了,这时操作中要用临时文件的名称tmp_name. //在客户端设置上传文件的限制(文件类型和大小)是不安全的,因为客户能通过源代码修改限制,所以在服务端这里设置限制. //设置编码为UTF-8,以避免中文乱码 header('Content-Type:text/ht

Java Web文件上传

一. Java Web文件上传需要借助一些第三方库,常用的是借助Apache的包,有两个: commons-fileupload commons-io 二.前端代码示例: <form method="post" id="uploadApkForm" action="uploadapk" enctype="multipart/form-data"> <p> 文件:<input name="

WEB文件上传下载过程简介(基于Struts2)

WEB文件上传过程简介(基于Struts2),页面上传.Action收取.解析:文件导出 文件处理过程,需要注意对文件的定期清理,避免磁盘占用过多: 1. jsp页面:   <s:file required="true" name ="myFile" theme="zx2"/> <s:form action ="myfile.action" name="form" method =&quo

Struts2单文件上传原理及示例

一.文件上传的原理 表单元素的enctype属性指定的是表单数据的编码方式,该属性有3个值: 1.application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式. 2.multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里. 3.text/plain:这种方式主要适用于直接通过表单发送邮件的

轻量级 web 文件上传组件,支持html5,支持上传进度显示(IE10+、标准浏览器),文件拖拽,降级支持IE6+

老早就注册了博客园帐号,昨天才发现,连博客都没开,Github也是一样,深觉惭愧,赶紧潜个水压压惊`(*∩_∩*)′ 言归正传.大概许多人都会用到文件上传的功能,上传的库貌似也不少,比如(jQuery File Uploader.FineUploader.Uploadify.Baidu Web Uploader 等等),功能都很强大,代码量一般也较大.当时心想,就这么个小功能,杀鸡焉用牛刀,用库的话还得熟悉它的用法,有的需要引入额外的库,纯Flash的不考虑,还是动手造个轮子得了,至少造过之后能

轻量级 web 文件上传组件,纯js,html5、html4智能适配,支持上传进度显示(IE10+、标准浏览器)

老早就注册了博客园帐号,昨天才发现,连博客都没开,Github也是一样,深觉惭愧,赶紧潜个水压压惊`(*∩_∩*)′ 言归正传.大概许多人都会用到文件上传的功能,上传的库貌似也不少,比如(jQuery File Uploader.FineUploader.Uploadify.Baidu Web Uploader 等等),功能都很强大,代码量一般也较大.当时心想,就这么个小功能,杀鸡焉用牛刀,用库的话还得熟悉它的用法,有的需要引入额外的库,纯Flash的不考虑,还是动手造个轮子得了,至少造过之后能

文件上传与下载学习笔记(1)---文件上传原理及配置

一:原理:将客户端的文件上传到服务器端的临时目录,再将服务器端的临时文件移动到指定目录. 二:客户端的配置 表单的method必须为post方法 表单必须添加enctype="multipart/form-data"属性 二者缺一不可. 三:将临时文件移动到指定目录 两种方法:1:move_uploaded_file($filename, $destination) 2:copy($source, $dest) 四:php.ini中的配置 在php.ini中搜索uploads ,会看到