이번에는 브라우저 파일의 분할된 중단점 업로드에 대해 소개하겠습니다. 브라우저 파일의 분할된 중단점 업로드에 대한 주의사항은 무엇인가요?
백엔드는 Python Flask를 사용합니다
프론트엔드 원칙은 다음과 같습니다.
1. 파일 기능 코드를 얻습니다
2. 파일 정보를 가로채서 파일을 분할합니다.
3. 동일한 기능 코드
4. 동일한 기능 코드를 가진 파일이 있으면 업로드 진행률을 가져옵니다
5. 그렇지 않으면 진행률은 0부터 시작됩니다.
6. 분할된 파일을 순서대로 반복하고 비동기 업로드합니다
7. 업로드가 완료되면, 프롬프트가 성공합니다
백엔드 원칙 구현:
요청(파일 해시) 매개변수 수신
파일 업로드가 중단되었는지 확인
해시 폴더가 존재하는 경우 폴더 아래의 파일 세그먼트 수를 가져와서 반환합니다. front end
존재하지 않는 경우 0 또는 비어 있음 String 5. 프런트 엔드가 업로드된 파일 세그먼트를 반환하면 파일 세그먼트를 저장하고 파일 세그먼트 식별을 인덱싱합니다.
업로드가 완료되고 파일을 병합합니다. , 파일 세그먼트 삭제
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 Code
예제를 위해 작성된 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 중국어 웹사이트의 다른 관련 기사를 주목하세요!
관련 읽기:
위 내용은 브라우저 파일 분할 중단점 업로드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!