您好,登錄后才能下訂單哦!
大文件上傳服務
一、前端
[webuploader](http://fex.baidu.com/webuploader/ ''webuploader'')
二、后端
django 2.0.0
這里只貼出核心的代碼:
前端的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="https://cdn.staticfile.org/webuploader/0.1.1/webuploader.css">
<link rel="stylesheet" type="text/css" >
<!--引入JS-->
<script type="text/javascript" src="https://cdn.staticfile.org/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/webuploader/0.1.1/webuploader.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/twitter-bootstrap/4.1.3/js/bootstrap.js"></script>
</head>
<body>
<div id="uploader" class="wu-example">
<!--用來存放文件信息-->
<div id="thelist" class="uploader-list"></div>
<div class="btns">
<div id="picker">選擇文件</div>
<button id="ctlBtn" class="btn btn-default">開始上傳</button>
</div>
<div class="progress"> <!-- 進度條 -->
<div class="progress-bar progress-bar-striped active" role="progressbar" ></div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var task_id = WebUploader.Base.guid(); //產生task_id
var uploader = WebUploader.create({ //創建上傳控件
swf: 'https://cdn.staticfile.org/webuploader/0.1.1/Uploader.swf', //swf位置,這個可能與flash有關
server: '/resource/files/upload/', //接收每一個分片的服務器地址
pick: '#picker', //填上傳按鈕的id選擇器值
auto: true, //選擇文件后,是否自動上傳
chunked: true, //是否分片
chunkSize: 10 * 1024 * 1024, //每個分片的大小,這里為10M
chunkRetry: 3, //某分片若上傳失敗,重試次數
threads: 1, //線程數量,考慮到服務器,這里就選了1
duplicate: true, //分片是否自動去重
formData: { //每次上傳分片,一起攜帶的數據
task_id: task_id,
},
});
uploader.on('startUpload', function() { //開始上傳時,調用該方法
$('.progress-bar').css('width', '0%');
$('.progress-bar').text('0%');
});
uploader.on('uploadProgress', function(file, percentage) { //一個分片上傳成功后,調用該方法
$('.progress-bar').css('width', percentage * 100 - 1 + '%');
$('.progress-bar').text(Math.floor(percentage * 100 - 1) + '%');
});
uploader.on('uploadSuccess', function(file) { //整個文件的所有分片都上傳成功,調用該方法
//上傳的信息(文件唯一標識符,文件名)
var data = {'task_id': task_id, 'filename': file.source['name'] };
$.get('/resource/upload/complete/', data); //ajax攜帶data向該url發請求
$('.progress-bar').css('width', '100%');
$('.progress-bar').text('上傳完成');
});
uploader.on('uploadError', function(file) { //上傳過程中發生異常,調用該方法
$('.progress-bar').css('width', '100%');
$('.progress-bar').text('上傳失敗');
});
uploader.on('uploadComplete', function(file) {//上傳結束,無論文件最終是否上傳成功,該方法都會被調用
$('.progress-bar').removeClass('active progress-bar-striped');
});
});
</script>
</body>
</html>
后端的:
路由
path('files/upload/', views.fileupload,name='圖片分片上傳'),
path('upload/complete/', views.fileMerge,name='上傳成功合并'),
視圖:
@csrf_exempt
def fileupload(request):
if request.method == 'POST':
upload_file = request.FILES.get('file')
task = request.POST.get('task_id') # 獲取文件唯一標識符
chunk = request.POST.get('chunk', 0) # 獲取該分片在所有分片中的序號
filename = '%s%s' % (task, chunk) # 構成該分片唯一標識符
print("filename=",filename)
default_storage.save('./upload/%s' % filename,ContentFile(upload_file.read())) # 保存分片到本地
return render_to_response('upload.html',locals())
@csrf_exempt
def fileMerge(request):
print(request.GET)
task = request.GET.get('task_id')
ext = request.GET.get('filename', '')
upload_type = request.GET.get('type')
if len(ext) == 0 and upload_type:
ext = upload_type.split('/')[1]
ext = '' if len(ext) == 0 else '.%s' % ext # 構建文件后綴名
chunk = 0
with open('./upload/%s%s' % (task, ext), 'wb') as target_file: # 創建新文件
while True:
try:
filename = './upload/%s%d' % (task, chunk)
source_file = open(filename, 'rb') # 按序打開每個分片
target_file.write(source_file.read()) # 讀取分片內容寫入新文件
source_file.close()
except IOError:
break
chunk += 1
os.remove(filename) # 刪除該分片,節約空間
return render_to_response('upload.html',locals())
效果圖:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。