Heim  >  Artikel  >  Web-Frontend  >  Hochladen segmentierter Haltepunkte für Browserdateien

Hochladen segmentierter Haltepunkte für Browserdateien

php中世界最好的语言
php中世界最好的语言Original
2018-03-10 15:52:262401Durchsuche

Dieses Mal werde ich Ihnen den segmentierten Haltepunkt-Upload von Browserdateien vorstellen. Was sind die Vorsichtsmaßnahmen für den segmentierten Haltepunkt-Upload von Browserdateien?

Das Backend verwendet Python Flask

Front-End-Prinzip-Implementierung:

1 Dateisignaturen abrufen und Dateien segmentieren

3. Überprüfen Sie, ob noch nicht abgeschlossene hochgeladene Dateien mit derselben Signatur auf dem Server vorhanden sind
4. Wenn Dateien mit derselben Signatur vorhanden sind, erhalten Sie den Upload-Fortschritt
5. Andernfalls beginnt der Fortschritt bei 0
6. Schleife asynchroner Upload in der Reihenfolge Segmentierte Datei
7. Wenn der Upload abgeschlossen ist, ist die Eingabeaufforderung erfolgreich

Implementierung des Backend-Prinzips:

Anforderungsparameter (Datei-Hash) empfangen

Stellen Sie fest, ob das Hochladen der Datei unterbrochen wurde

Wenn der Hash-Ordner vorhanden ist, ermitteln Sie die Anzahl der Dateisegmente unter dem Ordner und geben Sie ihn an das Frontend zurück

Wenn er nicht vorhanden ist, geben Sie 0 oder leer zurück

String
5. Wenn das Frontend das hochgeladene Dateisegment zurückgibt, speichern Sie das Dateisegment und geben Sie den Dateisegment-Identifikationsindex an Wenn der Upload abgeschlossen ist und die Datei zusammenführt, löschen Sie das Dateisegment

HTML-Code

Der Code verwendet als Beispiel einen einzelnen

Datei-Upload

. Verwenden Sie hashMe.js, um die Signatur zu erhalten

Python-Code
<!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>

Der für das Beispiel geschriebene Python-Code ist etwas unregelmäßig. Versuchen Sie bitte, meinen Schreibstil nicht zu imitieren (Mime-Download)

Es gibt so viele Beispiele, aber das eigentliche Problem ist nicht so einfach Beispielsweise können Sie vor dem Hochladen zur Überprüfung zunächst die Datei mit derselben Signatur und Größe abrufen, die bereits auf dem Server vorhanden ist, und die Datei dann direkt in das hochgeladene Verzeichnis kopieren oder nachfragen, ob Abdeckung usw. vorliegt. Natürlich können Sie auch optimieren, indem Sie beispielsweise Segmente hochladen und diese dann in Segmente hochladen und dann gleichzeitig die Segmente hochladen.
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()

Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website!


Verwandte Lektüre:

Eine Website, die NodeJS zur Einführung verwendet


Zuweisung und Symbol von ES6-Objekten


So erstellen Sie einen 1-Pixel-Randeffekt auf Mobilgeräten

Das obige ist der detaillierte Inhalt vonHochladen segmentierter Haltepunkte für Browserdateien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn