Maison  >  Article  >  interface Web  >  Exemple de didacticiel de téléchargement de fichiers volumineux par h5 dans des pages Web

Exemple de didacticiel de téléchargement de fichiers volumineux par h5 dans des pages Web

零下一度
零下一度original
2017-05-11 14:24:362700parcourir

UtiliserHTML5ShardingTéléchargerTrès gros fichiers

Télécharger directement des fichiers volumineux sur une page Web a toujours été un casse-tête. Les principaux problèmes incluent généralement deux types : Premièrement, si une erreur se produit pendant le temps de téléchargement, tous les efforts seront vains ; deuxièmement, la configuration du serveur est complexe et le problème de la réception de formulaires surdimensionnés et des délais d'attente doit être pris en compte. S'il s'agit d'un hôte géré, la configuration peut ne pas être effectuée. modifié et, par défaut, il ne peut recevoir que des pièces jointes inférieures à 4 Mo.

La solution idéale est de fragmenter les fichiers volumineux et de les envoyer un par un au serveur, puis le serveur les fusionne. L'avantage est qu'en cas d'échec du téléchargement, un seul fragment est perdu et le fichier entier n'a pas besoin d'être retransmis. De plus, la taille de chaque fragment peut être contrôlée dans la limite de 4 Mo et le serveur peut s'adapter sans effectuer de réglages. .

La solution couramment utilisée est RIA. En prenant flex comme exemple, la méthode FileReference.load est généralement utilisée pour charger le fichier pour obtenir un ByteArray, puis construire le formulaire en tranches (les versions supérieures de Flash ne le font pas). permettre un accès direct au fichier). Cependant, cette méthode de chargement ne peut charger que des fichiers plus petits, ne dépassant pas environ 300 Mo, son applicabilité n'est donc pas très forte.

Heureusement, maintenant que nous avons HTML5, nous pouvons directement construire des fragments. C'est un progrès très gratifiant, mais c'est dommage qu'il ne soit pas largement applicable à l'heure actuelle (IE, IE, je te déteste vraiment). beaucoup).

Revenons au fait, jetons un œil à une DEMO, basée sur ASP.Net MVC3, ce n'est qu'un exemple, et de nombreux problèmes ont été simplifiés.

Principalement côté client, les nouvelles fonctionnalités se reflètent ici :

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <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>
</head>
<body>
    <input type="file" id="file" />
    <button id="upload">上传</button>
    <span id="output" style="font-size:12px">等待</span>
</body>
</html>

La méthode slice et FormData ici n'existaient pas avant html5. Grâce à cette méthode, notre formulaire est construit comme ceci. Jetez un œil à la capture de paquets :

Exemple de didacticiel de téléchargement de fichiers volumineux par h5 dans des pages Web

Vous pouvez voir que le Content-Type construit est multipart/form-data. Il s’agit du formulaire de Téléchargement de fichiers le plus traditionnel, conforme aux normes RFC. De plus, le nom, le total et les autres attributs que nous transmettons en même temps sont également dans le formulaire.

Ensuite il y a le serveur, il n'y a rien de nouveau, il reçoit juste un fichier ordinaire :

[HttpPost]
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 <= total;++i)
        {
            string part = Path.Combine(dir, name + "_" + i);
            var bytes = System.IO.File.ReadAllBytes(part);
            fs.Write(bytes, 0, bytes.Length);
            bytes = null;
            System.IO.File.Delete(part);
        }
        fs.Close();
    }
   
    //返回是否成功,此处做了简化处理
    return Json(new { Error = 0 });
}

De nombreux problèmes dans la DÉMO ci-dessus sont simplifiés, par exemple, rien n'est fait Gestion des exceptions , le client ne juge pas s'il y a une erreur sur le serveur et réessaye, vous pouvez l'améliorer vous-même.

Sur la base de ce qui précède, nous pouvons créer de nombreuses extensions fonctionnelles. Par exemple, nous pouvons contrôler si tous les fragments sont téléchargés séquentiellement ou simultanément pour s'adapter à différentes applications. Pour un autre exemple, nous pouvons calculer le HASH correspondant avant de télécharger l'intégralité du fichier et avant de télécharger en partie, et envoyer une requête pour demander au serveur si le fichier existe déjà. S'il existe, ne le téléchargez pas à nouveau. . Ceci est réalisé. "Téléchargement extrêmement rapide" et "téléchargement avec reprise"

[Recommandations associées]

1. Tutoriel vidéo en ligne h5 gratuit

2 . Manuel de la version complète HTML5

3 Tutoriel vidéo HTML5 original php.cn

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn