Web上传文件的原理及实现

  现在有很多Web程序都有上传功能,实现上传功能的组件或框架也很多,如基于java的Commons FileUpload、还有Struts1.x和Struts2中带的上传文件功能(实际上,Struts2在底层也使用了Commons FileUpload)。

  虽然现在有很多上传组件可以利用,但是了解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方法中编写如下的代码。

 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所示:

由于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可以看出这一切。

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

啦啦啦

时间: 2024-12-28 00:13:40

Web上传文件的原理及实现的相关文章

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

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

前端之web上传文件的方式

前端之web上传文件的方式 本节内容 web上传文件方式介绍 form上传文件 原生js实现ajax上传文件 jquery实现ajax上传文件 form+iframe构造请求上传文件 1. web上传文件方式介绍 在web浏览器上传文件一般有以下几种方式: form表单上传文件 原生js实现ajax上传文件 jquery实现ajax上传文件 form+iframe上传文件 其中form提交数据之后会整个刷新页面:js通过ajax上传文件虽然不会刷新整个页面,但是他们都是通过使用formdata对

express 如何上传文件的原理和实现

express 上传文件的原理和实现 原理 formidable multer COS 1.原理 1.1 要想了解express上传 我们先看看 nodejs原生上传是怎么实现的 let server = require('http').Server(app); server.listen(3000); 首先为了让express拥有原始http模块的一些功能 请不要使用 bodyParser 之类的中间件 因为不会next到这里 保持尽量原生. app.post('/upload', async

.NET Core 2.1 Web 上传文件 关于System.IO.DirectoryNotFoundException

在ASP.NET Web开发练习中,想要完成上传文件的功能: 代码为: View: 1<form method="post" asp-controller="Register" asp-action="SetIcon" enctype="multipart/form-data"> 2 <input name="file" type="file" accept="

web上传文件——python

上传文件 a. Form表单上传,页面刷新(基本不用这种方式) b. Ajax方式: $(function () { $('#btn1').click(function () { var fm = new FormData(); fm.append('fffff', document.getElementById('ggggg').files[0]); fm.append('usernmae','root'); $.ajax({ url: "/ajax-upload/", type:

ajax上传文件的原理与实现

    ajax已经很普遍了,但使用 ajax上传文件自己却一直都没有涉及,我只知道挺复杂的,上传文件不同于上传一般的表单数据,必须特殊处理,知道一般ajax使用上传都是应用一个虚拟的iframe,但由于项目需要,在网上找了找,没想到找到了两个支持ajax上传文件的jquery插件,jquery.uploadify.js和dropzone.min.js两个都可以实现ajax上传文件,效果也不错. 1使用jquery.uploadify.js上传文件  这种上传方式,使用了Flash,因此需要引用

隐藏iframe无刷新上传文件

首先ajax不能上传文件,这误导了我有段时间,今晚睡不着就照着说明做了个无刷新上传文件 其实原理很简单 <form enctype="multipart/form-data" method="POST" target="upload" action="http://localhost/class.upload.php" > <input type="file" name="upl

atitit.ajax上传文件的实现原理 与设计

atitit.ajax上传文件的实现原理 与设计 1. 上传文件的三大难题 1 1.1. 本地预览 1 1.2. 无刷新 1 1.3. 进度显示 1 2.  传统的html4  + ajax 是无法直接实现上传文件 1 2.1. 传统的实现方式iframe 2 2.2. html5转码base64 3 2.3. 其它插件FLASH的实现原理 3 3. 上传进度的实现原理 3 3.1. 使用ajax结合服务端的进度返回,比較麻烦 4 4. 本地预览的解决 4 4.1. 用HTML5上传文件 4 5

web 开发之js---巧用iframe实现jsp无刷新上传文件

首先要说的就是 ajax 是无法实现上传文件的,可以想一下ajax与后台通信都是通过传递字符串,怎么能传递文件呢?其实出于安全考虑js是不能操作文件的,所以就不要再说用ajax来实现文件的上传了,这是不可能的.    而本文实现的文件上传也是无页面刷新的,可以说是一种"类似AJAX"方法.    开始之前先说两句无关的,其实在ajax出现之前,web应用也可以是无刷新的,那时大多通过IFrame来做到这一点.当然Ajax出现之后,人们一窝蜂地投奔Ajax 的阵营了,iFrame 就乏人