今回はブラウザファイルの分割ブレークポイントアップロードについて紹介します。ブラウザファイルの分割ブレークポイントアップロードの注意事項を実際のケースで見てみましょう。
バックエンドは 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['UPLOAD_FOLDER'] = 'uploads/'#保存文件位置app.url_map.converters['regex'] = RegexConverter@app.route('/<regex(".*"):url>')def index(url): ps=urllib.parse.unquote(url) if ps=="upload": return upload() elif ps.split('?')[0]=="upload_ck": if os.path.exists("./"+app.config['UPLOAD_FOLDER']+str(request.args.get('hash') ) ): return str(len( os.listdir("./"+app.config['UPLOAD_FOLDER']+str(request.args.get('hash') )) )-1 )#返回文件段索引 else: return "" bt=codecs.open(ps,'rb',"utf-8").read() return bt, 200, {'Content-Type': mim[url.split(".")[-1]]}@app.route('/upload', methods=['POST'])def upload(): hashtxt=request.form['hash'] sPs="./"+app.config['UPLOAD_FOLDER']+hashtxt+"/" if not os.path.exists(sPs):#文件夹不存在 os.makedirs(sPs)#创建hash文件夹 uploaded_files = request.files.getlist("blob")#获取文件流集 filePs=hashtxt+"/"+request.form['name']+".part"+request.form['sdIndex'] #文件段保存路径 for file in uploaded_files: file.save(os.path.join(app.config['UPLOAD_FOLDER'],filePs ))#保存文件 if (int(request.form['shardCount']))==(int(request.form['sdIndex'])):#判断上传完最后一个文件 mergeFile(app.config['UPLOAD_FOLDER'],request.form['name'],hashtxt);#合并文件 shutil.rmtree("./"+app.config['UPLOAD_FOLDER']+hashtxt)#删除 return request.form['sdIndex']#返回段索引 def mergeFile(ps,nm,hs):#合并文件 temp = open(ps+"/"+nm,'wb')#创建新文件 count=len(os.listdir(ps+"/"+hs)) for i in range(0,count): fp = open(ps+"/"+hs+"/"+nm+".part"+str(i), 'rb')#以二进制读取分割文件 temp.write(fp.read())#写入读取数据 fp.close() temp.close()with app.test_request_context(): #输出url passif name == 'main': app.debug = True app.run()
例はたくさんありますが、実際の問題は、同じようにファイルをアップロードする前に取得するなど、それほど単純ではありません。既存の署名とサイズを選択し、アップロードされたディレクトリにファイルを直接コピーするか、上書きするかどうかなどを確認します。もちろん、セグメントをアップロードしてからセグメントにアップロードし、セグメントを同時にアップロードするなどの最適化も可能です。
この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。
関連書籍:
以上がブラウザファイルのセグメント化されたブレークポイントのアップロードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。