ホームページ  >  記事  >  ウェブフロントエンド  >  ブラウザファイルのセグメント化されたブレークポイントのアップロード

ブラウザファイルのセグメント化されたブレークポイントのアップロード

php中世界最好的语言
php中世界最好的语言オリジナル
2018-03-10 15:52:262442ブラウズ

今回はブラウザファイルの分割ブレークポイントアップロードについて紹介します。ブラウザファイルの分割ブレークポイントアップロードの注意事項を実際のケースで見てみましょう。

バックエンドは Python Flask を使用します

フロントエンドの原則は次のように実装されています:

1. ファイルの機能コードを取得します
2. ファイル情報を傍受し、ファイルをセグメント化します
3.同じ機能コード
4. 同じ機能コードを持つファイルがある場合、アップロードの進行状況を取得します
5. それ以外の場合、進行状況は 0 から始まります
6. セグメント化されたファイルを順番にループして非同期アップロードします
7. アップロードが完了したら、プロンプトは成功です

バックエンド原則の実装:

リクエスト (ファイルハッシュ) パラメータを受信します

ファイルのアップロードが中断されたかどうかを判断します

ハッシュフォルダーが存在する場合、フォルダーの下にあるファイルセグメントの数を取得し、それを返しますフロントエンド
存在しない場合は、0 または空の 文字列 5. フロントエンドがアップロードされたファイルセグメントを返した場合、ファイルセグメントを保存し、ファイルセグメント ID にインデックスを付けます

アップロードが完了した場合は、ファイルをマージします、ファイルセグメントを削除します

htmlコード

このコードは例として単一のファイルアップロードを使用します、hashMe.jsを使用して機能コードを取得します

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

Pythonコード

この例のために書かれたPythonコードは少しです私の書き方(マイムダウンロード)は真似しないでください

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()

例はたくさんありますが、実際の問題は、同じようにファイルをアップロードする前に取得するなど、それほど単純ではありません。既存の署名とサイズを選択し、アップロードされたディレクトリにファイルを直接コピーするか、上書きするかどうかなどを確認します。もちろん、セグメントをアップロードしてからセグメントにアップロードし、セグメントを同時にアップロードするなどの最適化も可能です。

この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。

関連書籍:

nodejsを使用したWebサイトの紹介

ES6オブジェクトの割り当てとシンボル

モバイル側で1pxの境界線効果を作成する方法

以上がブラウザファイルのセグメント化されたブレークポイントのアップロードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。