要通过HTTP上传文件首先要在提交的form的定义中加入ENCTYPE="multipart/form-data"类型标示,然后使用<input type="file"...>标识,用户就可以在浏览时使用该input框选取要上传的文件。
这样在form提交后将自动把文件数据一同上传到Server端,此时必须使用request对象的binaryread方法取数据才能读文件数据并进行相应操作,如果使用response对象的binarywrite方法将数据显示在页面上你就会看到事实上所有的文件数据和form表格内部数据全都混杂在一起,而调用页面的"?"后面的参数也全部丢失了。
下面附一个完整的数据上传结果,我们将在此基础上对所上传的数据进行分析。上传的数据中有2个文本输入框,分别名称"text"和"FileNumber"(FileNumber表示上传的文件数),一个checkbox,名称"check",两个文件上传,名称"File"和"File1"(该名称由上传页脚本自动计算生成),以及一个"submit"按钮,名称"Submit",值为"确定"。为了使数据比较清晰我选择了两个文本文件进行上传,如果上传二进制文件其效果是一样的。具体上传数据如下:
-----------------------------7d18e2d3f01e0 Content-Disposition: form-data; name="check" on -----------------------------7d18e2d3f01e0 Content-Disposition: form-data; name="FileNumber" 2 -----------------------------7d18e2d3f01e0 Content-Disposition: form-data; name="File0"; filename="D:/Starcraft/sc.reg" Content-Type: application/octet-stream REGEDIT4 [HKEY_CURRENT_USER/Software/Battle.net/Configuration] "Battle.net gateways"=hex(7):31,30,30,30,00,30,31,00,31,39,32,2e,31,36,38,2e,/ 31,30,32,2e,38,36,00,2d,39,00,42,50,55,20,35,23,20,53,65,72,76,65,72,00,75,/ 73,77,65,73,74,2e,62,61,74,74,6c,65,2e,6e,65,74,00,38,00,55,2e,53,2e,20,57,/ 65,73,74,00,75,73,65,61,73,74,2e,62,61,74,74,6c,65,2e,6e,65,74,00,36,00,55,/ 2e,53,2e,20,45,61,73,74,00,61,73,69,61,2e,62,61,74,74,6c,65,2e,6e,65,74,00,/ 2d,39,00,41,73,69,61,00,65,75,72,6f,70,65,2e,62,61,74,74,6c,65,2e,6e,65,74,/ 00,2d,31,00,45,75,72,6f,70,65,00,00 [HKEY_LOCAL_MACHINE/SOFTWARE/Battle.Net/Configuration] "Server List"="192.168.102.86" "Server Version"=dword:00000001 -----------------------------7d18e2d3f01e0 Content-Disposition: form-data; name="File1"; filename="C:/cheaters.log" Content-Type: application/octet-stream Windows renabled Windows renabled Windows renabled Windows renabled Windows renabled -----------------------------7d18e2d3f01e0 Content-Disposition: form-data; name="text" asdf -----------------------------7d18e2d3f01e0 Content-Disposition: form-data; name="submit" 确定 -----------------------------7d18e2d3f01e0-- |
这只是一个小例子,从中我们可以简单的分析一下ASP的流式上传数据格式,如下(对于类似的数据段,我只挑其中一个介绍):
1."-----------------------------7d12a925602d2"
这是用来唯一标识一次上传的编码,该数字自动生成并且保证任意两次上传绝对不会有相同的标识,同时也是用来分隔各输入框数据的分隔符,在数据传输的最后由该字符串后跟"--"标识。在上面的例子中该字串被标为红色粗体,以便于区分各个数据段。
2."Content-Disposition: form-data;"
用来表示该数据段为form提交的数据。
3.name="check"
数据框的名称,大家平时都是使用request.form("check")读取这个CheckBox的内容。
4."on"
CheckBox数据框的内容,也就是request.form("check")的返回值,CheckBox类型输入框(复选框)被选中时提交"on",未被选中时不提交数据(即上传结果中根本不出现)。
5.filename="D:/Starcraft/sc.reg"
上面所说的type="file"的input框会把文件在客户端的路径传到服务器,使用的就是这个字段,这一句表示上传的文件为D盘Starcraft目录下的sc.reg(星际争霸的注册文件)。
6.Content-Type: application/octet-stream
说明是文件上传,同时说明为流式上传。
7.文件数据
文件数据是以两个VbCrLf(硬回车)表示开始的,文件数据结束后也是两个VbCrLf。例子中用蓝色标出。
除"file"外所有的输入方式上传后结果都是一样的,如下:
-----------------------------7d139414602d2
Content-Disposition: form-data; name="text"
(此处为空行)
asdf
表示由form提交的名称为text的输入框,其值为asdf。
ASP不能轻松的上传文件主要原因是ASP没有权限在Server端写二进制文件,只能写文本,而且一旦对request对象使用了binaryread方法就不能再使用以前的request("字段名称")这种方式读取数据了,所以一般都使用拆分写入数据库或使用组件上传。(本站KKnD最近写了一个功能强大的上传组件,如有需要可以在ASP下在仓库中下载到。)
为了让大家能实际的看到数据上传效果,我提供两个ASP文件的源码,分别用来上传和分析上传数据。
上传页源码 |
<!--该页为普通HTML页面即可--> |
接收页源码 |
<%@ CODEPAGE = "936" %> |