Web上传文件的原理及实现

简介:
现在有很多Web 程序都有上传功能,实现上传功能的组件或框架也很多,如基于java Commons FileUpload 、还有Struts1.x Struts2 中带的上传文件功能(实际上,Struts2 在底层也使用了Commons FileUpload )。在asp.net 中也有相应的上传文件的控件。
虽然现在有很多上传组件可以利用,但是了解Web 上传文件的原理,对于处理突然出现的问题会有很大的帮助,下面就来讲一下通过浏览器上传文件的基本原理。在了解了原理之后,就可以非常容易地自制满足自身需要的上传组件了。
众所周知,在客户端代码中需要使用 <input type='file' name='file' /> 来选择要上传的文件,并上传,代码如上:

< html >
    
< head >
        
< title > upload </ title >
        
< meta  http-equiv ="description"  content ="this is my page" >
        
< meta  http-equiv ="content-type"  content ="text/html; charset=GB18030" >
    
</ head >

    
< body >
        
< form  action ="servlet/UploadFile"  method ="post"
            enctype
="multipart/form-data" >
            
< input  type ="file"  name ="file1"  id ="file1"   />
            
< input  type ="file"  name ="file2"  id ="file2"   />
            
< input  type ="submit"  value ="上传"   />
        
</ form >
    
</ body >
</ html >

从上面的代码可以看出,有两个文件选择框(file1 file2 ),在上传文件时,<form> 标签必须加上enctype="multipart/form-data" ,否则浏览器无法将文件内容上传到服务端。下面我们来做个实验。在Servlet doPost 方法中编写如下的代码,如果想使用asp.net 或其他的语言或技术,也可以很容易实现相应的功能。
     public   void  doPost(HttpServletRequest request, HttpServletResponse response)
            
throws  ServletException, IOException
    {
        java.io.InputStream is 
=  request.getInputStream();
        java.io.FileOutputStream fos 
=   new  java.io.FileOutputStream( " d:\\out.txt " );
        
        
byte [] buffer  =   new   byte [ 8192 ];
        
int  count  =   0 ;
        
while ((count  =  is.read(buffer))  > 0 )
        {
            fos.write(buffer, 
0 , count);
        }        
        fos.close();
    }

    上面的功能非常简单,只是通过 request 获得一个 InputStream 对象,并通过这个对象从客户端获得发送过来的字节流(注意,一定要用字节流,因为,上传的文件可能是二进制文件,如图象文件,因此,使用字节流会更通用)。并将这些字节流保存在 D 盘的 out.txt 文件中。然后我们打开 out.txt ,文件的内容如图 1 所示:



                                                                                          图1
     由于out.txt 是使用文本形式打开的,并且file1 上传的是a.jpg( 一个图象文件) ,因此,显示的是一些乱码。我们可以不用管它们。只需要看看这些内容的头部。我们很快就可以找到规律。每一个文件内容的头部都由“-----------------------------30514443229777 ”分隔,然后是这个文件的属性,如下:

Content-Disposition: form-data; name="file1"; filename="a.jpg"
Content-Type: image/jpeg
其中包含了文件选择框的name 属性,还有上传的文件名(filename 字段),要注意的,firefox 在上传时,这个filename 属性值只是文件名,如果使用IE ,就是带路径的文件名,如D:"a.jpg
接下来的规则就和HTTP 的头一样了,以一个空行("r"n )分隔。后面就是文件的具体内容。现在最关键的文件的结尾,从图1 可以看出,文件的结尾也是“-----------------------------30514443229777 ”,因此,可以断定,第一个上传的文件(包括文件头)是夹在两个“-----------------------------30514443229777 ”之间的。而“-----------------------------30514443229777 ”就是multipart/form-data 协议的分隔符。但这里还有一个最关键的问题。这个分隔符每次上传都不一样,服务端是如何知道每次上传的这个分隔符的呢?
实际上,这个分隔符是通过HTTP 请求头的Content-Type 字段获得,可通过下面的代码输出这个字段值:

System.out.println(request.getHeader("Content-type"));
输出的内容如下:

multipart/form-data; boundary=---------------------------106712230227687
只要在服务端获得boundary 后面的值即可。经过测试,Content-Type 中的分隔符号中的“- ”比实际上传的“- ”少两个,不知是怎么回事。不过这没关系,我们可以认为每一个文件块是以""r"n— “结尾的,或是直接将从boundary 获得的分隔符加两个“”。而最后结尾的分隔符是“---------------------------106712230227687— ”,后面多了两个“”。
综合上述,也就是说,一个文件块是以“---------------------------106712230227687 ”开头,以“”结尾,从图2 可以看出这一切。



                                  图2
     至于剩下的工作,就是按着上面的规则来分析这些字符流了。分析的方法很多。在这里就不详述了。

multipart/form-data 规 范原文:http://www.ietf.org/rfc/rfc2388.txt
Form-based File Upload in HTML:http://www.ietf.org/rfc/rfc1867.txt





 本文转自 androidguy 51CTO博客,原文链接:http://blog.51cto.com/androidguy/215335 ,如需转载请自行联系原作者

相关文章
|
8月前
|
安全 Java 程序员
Web安全性测试系列(三)文件上传漏洞核心原理详解
Web安全性测试系列(三)文件上传漏洞核心原理详解
|
2月前
|
前端开发 JavaScript 安全
深入探索 Qt6 web模块 WebEngineCore:从基础原理到高级应用与技巧
深入探索 Qt6 web模块 WebEngineCore:从基础原理到高级应用与技巧
96 0
|
2月前
|
Web App开发 存储 搜索推荐
谈谈 Web 应用里界面图标 Icon 的显示原理
谈谈 Web 应用里界面图标 Icon 的显示原理
28 0
|
4月前
|
Web App开发 Ubuntu 应用服务中间件
Flutter笔记:Web支持原理与实践
Flutter笔记:Web支持原理与实践
110 0
|
4月前
|
安全 Java 应用服务中间件
Web服务器的工作原理
Web服务器的工作原理
|
5月前
|
JSON 算法 数据库
JWT(JSON Web Token)的基本原理
JWT(JSON Web Token)的基本原理
|
8月前
|
安全 网络协议 网络安全
Web安全性测试系列(二)DDOS拒绝服务攻击原理详解
Web安全性测试系列(二)DDOS拒绝服务攻击原理详解
|
8月前
|
负载均衡 安全 网络协议
01-基础设施安全-3-WEB应用防火墙-ACA-02-核心能力与接入原理
01-基础设施安全-3-WEB应用防火墙-ACA-02-核心能力与接入原理
128 0
|
9月前
|
SQL 存储 安全
常见web安全及防护原理?
常见web安全及防护原理?
68 0
|
9月前
|
前端开发 UED
响应式Web设计的原理与实践
响应式Web设计的原理与实践