首頁 web前端 html教學 html5 分片/分块/分割上传超大文件

html5 分片/分块/分割上传超大文件

Jun 01, 2016 am 09:53 AM
html 上傳 文件

在网页中直接上传大文件一直是个比较头疼的问题,主要面临的问题一般包括两类:一是上传时间长中途一旦出错会导致前功尽弃;二是服务端配置复杂,要考虑接收超大表单和超时问题,如果是托管主机没准还改不了配置,默认只能接收小于4MB的附件。

比较理想的方案是能够把大文件分片,一片一片的传到服务端,再由服务端合并。这么做的好处在于一旦上传失败只是损失一个分片而已,不用整个文件重传,而且每个分片的大小可以控制在4MB以内,服务端不用做任何设置就可适应。

常用的解决方案是RIA,以flex为例,通常是利用FileReference.load方法加载文件得到ByteArray,然后分片构造表单(flash的高版本不允许直接访问文件)。不过这个load方法只能加载较小的文件,大约不超过300MB,因此适用性不是很强。

好在现在有了HTML5,我们可以直接构造分片了,这是一个非常喜人的进步,只可惜目前适用面不广(IE啊IE,真是恨你恨得牙痒痒)。

言归正传,来看一个DEMO吧,基于ASP.Net MVC3,只是示例,很多问题做了简化处理。

主要是客户端,新特性都体现在这里:

<code class="html">" %>







    <meta charset="utf-8">

    <title>HTML5大文件分片上传示例</title>

    <script src="../Scripts/jquery-1.11.1.min.js"></script>

    <script>

    var page = {

        init: function(){

            $("#upload").click($.proxy(this.upload, this));

        },

       

        upload: function(){

            var file = $("#file")[0].files[0],  //文件对象

                name = file.name,        //文件名

                size = file.size,        //总大小

                succeed = 0;

                 

            var shardSize = 2 * 1024 * 1024,    //以2MB为一个分片

                shardCount = Math.ceil(size / shardSize);  //总片数

                 

            for(var i = 0;i < shardCount;++i){

                //计算每一片的起始与结束位置

                var start = i * shardSize,

                    end = Math.min(size, start + shardSize);

 

                //构造一个表单,FormData是HTML5新增的

                var form = new FormData();

                form.append("data", file.slice(start,end));  //slice方法用于切出文件的一部分

                form.append("name", name);

                form.append("total", shardCount);  //总片数

                form.append("index", i + 1);        //当前是第几片

               

                //Ajax提交

                $.ajax({

                    url: "../File/Upload",

                    type: "POST",

                    data: form,

                    async: true,        //异步

                    processData: false,  //很重要,告诉jquery不要对form进行处理

                    contentType: false,  //很重要,指定为false才能形成正确的Content-Type

                    success: function(){

                        ++succeed;

                        $("#output").text(succeed + " / " + shardCount);

                    }

                });

            }

        }

    };

    $(function(){

        page.init();

    });

    </script>





    <input type="file" id="file">

    <button id="upload">上传</button>

    <span id="output" style="font-size:12px">等待</span>



</code>
登入後複製

这里的slice方法和FormData都是html5之前不存在的。通过这样的方法,我们的表单构造出来是这样的,抓包看看:

html5 分片/分块/分割上传超大文件

可以看到构造出来的Content-Type是multipart/form-data,也就是符合RFC标准的那个最传统的文件上传表单。另外我们同时传输的name、total等属性也都在表单里。

然后是服务端,没什么新鲜的,完全是在接收一个普通的文件:

<code class="java">public ActionResult Upload()

{

    //从Request中取参数,注意上传的文件在Requst.Files中

    string name = Request["name"];

    int total = Convert.ToInt32(Request["total"]);

    int index = Convert.ToInt32(Request["index"]);

    var data = Request.Files["data"];

   

    //保存一个分片到磁盘上

    string dir = Server.MapPath("~/Upload");

    string file = Path.Combine(dir, name + "_" + index);

    data.SaveAs(file);

   

    //如果已经是最后一个分片,组合

    //当然你也可以用其它方法比如接收每个分片时直接写到最终文件的相应位置上,但要控制好并发防止文件锁冲突

    if(index == total)

    {

        file = Path.Combine(dir, name);

        var fs = new FileStream(file, FileMode.Create);

        for(int i = 1;i </code>
登入後複製

上面的DEMO很多问题是简化处理的,比如没做什么异常处理,客户端也没有判断服务端是否出错重试一类的,各位可以自己完善。

在上面的基础上,我们可以做很多功能上的扩展,比如我们可以控制所有分片是顺序上传还是并发上传,以适用不同应用。再比如我们可以在整体文件上传前以及分片上传前都先计算一下相应的HASH,发个请求询问服务器文件是否已存在,如果存在就不要重复上传了,这样就实现了“极速上传”以及“断点续传”。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

HTML 中的表格邊框 HTML 中的表格邊框 Sep 04, 2024 pm 04:49 PM

HTML 表格邊框指南。在這裡,我們以 HTML 中的表格邊框為例,討論定義表格邊框的多種方法。

HTML 左邊距 HTML 左邊距 Sep 04, 2024 pm 04:48 PM

HTML 左邊距指南。在這裡,我們討論 HTML margin-left 的簡要概述及其範例及其程式碼實作。

HTML 中的巢狀表 HTML 中的巢狀表 Sep 04, 2024 pm 04:49 PM

這是 HTML 中巢狀表的指南。這裡我們討論如何在表中建立表格以及對應的範例。

HTML 表格佈局 HTML 表格佈局 Sep 04, 2024 pm 04:54 PM

HTML 表格佈局指南。在這裡,我們詳細討論 HTML 表格佈局的值以及範例和輸出。

HTML 輸入佔位符 HTML 輸入佔位符 Sep 04, 2024 pm 04:54 PM

HTML 輸入佔位符指南。在這裡,我們討論 HTML 輸入佔位符的範例以及程式碼和輸出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在這裡我們也分別討論了 HTML 有序列表和類型的介紹以及它們的範例

在 HTML 中移動文字 在 HTML 中移動文字 Sep 04, 2024 pm 04:45 PM

HTML 中的文字移動指南。在這裡我們討論一下marquee標籤如何使用語法和實作範例。

HTML onclick 按鈕 HTML onclick 按鈕 Sep 04, 2024 pm 04:49 PM

HTML onclick 按鈕指南。這裡我們分別討論它們的介紹、工作原理、範例以及各個事件中的onclick事件。

See all articles