Maison  >  Article  >  interface Web  >  Téléchargement de points d'arrêt segmentés de fichiers du navigateur

Téléchargement de points d'arrêt segmentés de fichiers du navigateur

php中世界最好的语言
php中世界最好的语言original
2018-03-10 15:52:262445parcourir

Cette fois, je vais vous présenter le téléchargement de points d'arrêt segmenté des fichiers du navigateur. Quelles sont les précautions pour le téléchargement de points d'arrêt segmenté des fichiers du navigateur. Voici un cas pratique, jetons un coup d'œil.

Le backend utilise Python Flask

Implémentation du principe du front-end :

1 Obtenir les signatures de fichiers
2 Intercepter les informations sur les fichiers et segmenter les fichiers
3 . Vérifiez s'il y a des fichiers téléchargés inachevés avec la même signature sur le serveur
4. S'il y a des fichiers avec la même signature, obtenez la progression du téléchargement
5. Sinon, la progression commence à 0
6. Boucle téléchargement asynchrone dans l'ordre Fichier segmenté
7. Si le téléchargement est terminé, l'invite réussit

Implémentation du principe du backend :

Paramètre de demande de réception (hachage de fichier)

Déterminez si le téléchargement du fichier a été interrompu

Si le dossier de hachage existe, obtenez le nombre de segments de fichier sous le dossier et renvoyez-le au front-end
S'il n'existe pas, renvoyez 0 ou vide String 5. Si le front-end renvoie le segment de fichier téléchargé, enregistrez-le Segment de fichier et donnez l'index du segment de fichier

Si le téléchargement est terminé et fusionnez le fichier, supprimez le segment de fichier

Code HTML

Le code prend un seul téléchargement de fichier comme exemple, utilisez hashMe.js pour obtenir la signature

<!DOCTYPE html><html><head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="md5.js"></script>
    <script src="hashme.js"></script></head><body>
    <input type="file" onchange="hhh(this.files[0])" />
    <button onclick="uploadCk()">测试</button>
    <script>
        var up_f;//需要上传的信息
        var fileSplitSize = 1024 * 1024 * 2; //以2MB为一个分片
        function hhh(f) {             if (true) { //假设这是判断文件大小
                var hash = new hashMe(f, function(msg) {
                    up_f = new Object();
                    up_f.hash = msg;
                    up_f.name = f.name;
                    up_f.size = f.size;
                    up_f.shardCount = Math.ceil(f.size / fileSplitSize); //总片数
                    up_f.shard = [];//文件段
                    for (var i = 0; i < up_f.shardCount; i++) {                        var start = i * fileSplitSize;                        var end = Math.min(f.size, start + fileSplitSize);
                        up_f.shard[up_f.shard.length] = f.slice(start, end);//保存分段
                    }
                });
            }
        }        function uploadCk() { //上传前检查 
            $.ajax({                url: "/upload_ck",                type: "get",                data: {                    hash: up_f.hash
                },                success: function(data) {                    if (data != "") {
                        upload(Number(data));//调用上传(索引为服务器存在的文件段索引)
                    } else { 
                        upload(0);//调用上传
                    }
                }
            });
        }        function upload(loadIndex) { //上传
            var form = new FormData();
            form.append("hash", up_f.hash);
            form.append("name", up_f.name);
            form.append("size", up_f.size);
            form.append("shardCount", up_f.shardCount);
            form.append("blob", up_f.shard[loadIndex]);
            form.append("sdIndex", loadIndex);            console.log("sdIndex:" + loadIndex + ",shardCount:" + up_f.shardCount)
            $.ajax({                url: "/upload",                type: "POST",                data: form,                async: true, 
                processData: false, //很重要,告诉jquery不要对form进行处理
                contentType: false, //很重要,指定为false才能形成正确的Content-Type
                success: function(data) {
                    data = Number(data) + 1;                    if (data <= up_f.shardCount) {                        console.log("data:" + data);
                        upload(data);
                    } else {                        console.log("上传完毕");
                    }
                }
            });
        }    </script></body></html>

Code Python

Le code Python écrit pour l'exemple est quelque peu irrégulier. Veuillez essayer de ne pas imiter mon style d'écriture (téléchargement mime)

from flask import Flask, url_for,request 
import codecs,re,osimport urllib.parse,mimeimport shutilfrom werkzeug.routing import BaseConverterclass RegexConverter(BaseConverter):
    def init(self, map, *args):
        self.map = map
        self.regex = args[0]
        
app = Flask(name)
mim=mime.types
app.config[&#39;UPLOAD_FOLDER&#39;] = &#39;uploads/&#39;#保存文件位置app.url_map.converters[&#39;regex&#39;] = RegexConverter@app.route(&#39;/<regex(".*"):url>&#39;)def index(url):
    ps=urllib.parse.unquote(url)   
    if ps=="upload":        return upload()    elif ps.split(&#39;?&#39;)[0]=="upload_ck":        if os.path.exists("./"+app.config[&#39;UPLOAD_FOLDER&#39;]+str(request.args.get(&#39;hash&#39;) ) ):            return str(len( os.listdir("./"+app.config[&#39;UPLOAD_FOLDER&#39;]+str(request.args.get(&#39;hash&#39;) )) )-1 )#返回文件段索引
        else:            return ""
    bt=codecs.open(ps,&#39;rb&#39;,"utf-8").read() 
    return  bt, 200, {&#39;Content-Type&#39;: mim[url.split(".")[-1]]}@app.route(&#39;/upload&#39;, methods=[&#39;POST&#39;])def upload():
    hashtxt=request.form[&#39;hash&#39;]
    sPs="./"+app.config[&#39;UPLOAD_FOLDER&#39;]+hashtxt+"/"
    if not os.path.exists(sPs):#文件夹不存在
        os.makedirs(sPs)#创建hash文件夹
    uploaded_files = request.files.getlist("blob")#获取文件流集
    filePs=hashtxt+"/"+request.form[&#39;name&#39;]+".part"+request.form[&#39;sdIndex&#39;] #文件段保存路径
    for file in uploaded_files:  
        file.save(os.path.join(app.config[&#39;UPLOAD_FOLDER&#39;],filePs ))#保存文件
    if (int(request.form[&#39;shardCount&#39;]))==(int(request.form[&#39;sdIndex&#39;])):#判断上传完最后一个文件
        mergeFile(app.config[&#39;UPLOAD_FOLDER&#39;],request.form[&#39;name&#39;],hashtxt);#合并文件
        shutil.rmtree("./"+app.config[&#39;UPLOAD_FOLDER&#39;]+hashtxt)#删除
    return request.form[&#39;sdIndex&#39;]#返回段索引
 
        def mergeFile(ps,nm,hs):#合并文件
    temp = open(ps+"/"+nm,&#39;wb&#39;)#创建新文件
    count=len(os.listdir(ps+"/"+hs))    for i in range(0,count):  
        fp = open(ps+"/"+hs+"/"+nm+".part"+str(i), &#39;rb&#39;)#以二进制读取分割文件
        temp.write(fp.read())#写入读取数据
        fp.close()  
    temp.close()with app.test_request_context():    #输出url
    passif name == &#39;main&#39;: 
    app.debug = True
    app.run()

Il y a tellement d'exemples, mais le problème réel n'est pas si simple. Par exemple, avant de télécharger pour vérification, vous pouvez d'abord obtenir le fichier avec la même signature et la même taille qui existe déjà sur le serveur, puis copier directement le fichier dans le répertoire téléchargé ou demander si la couverture et plus encore. Bien sûr, vous pouvez également optimiser, par exemple en téléchargeant des segments, puis en les téléchargeant dans des segments, puis en téléchargeant les segments en même temps.

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture connexe :

Un site Web utilisant nodejs pour l'introduction

Affectation et symbole des objets ES6

Comment créer un effet de bordure de 1px sur mobile

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