這篇文章主要介紹了Vue2.0結合webuploader實現文件分片上傳功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
Vue專案中遇到了大文件分片上傳的問題,之前用過webuploader,索性就把Vue2.0與webuploader結合使用,封裝了一個vue的上傳元件,使用起來也比較舒爽。
上傳就上傳吧,為什麼搞得那麼麻煩,用分片上傳?
分片與並發結合,將一個大檔案分割成多區塊,並發上傳,大幅提高大檔案的上傳速度。
當網路問題導致傳輸錯誤時,只需要重傳出錯分片,而不是整個檔案。另外分片傳輸能夠更即時的追蹤上傳進度。
實作後的介面:
主要是兩個文件,封裝的上傳元件和特定的ui頁面,上傳元件程式碼下面有列出來。這兩個頁面的程式碼放到github上了: https://github.com/shady-xia/Blog/tree/master/vue-webuploader 。
在專案中引入webuploader
1.先在系統中引入jquery(外掛程式基於jq,坑爹啊!),如果你不知道放哪,那就放到index.html 裡。
2.在官網上下載 Uploader.swf
和webuploader.min.js
,可以放到專案靜態目錄static 下面;在index.html 中引入webuploader .min.js。
(无需单独再引入 webuploader.css ,因为没有几行css,我们可以复制到vue组件中。) <script src="/static/lib/jquery-2.2.3.min.js"></script> <script src="/static/lib/webuploader/webuploader.min.js"></script>
需要注意的點:
1.在vue元件中,透過 import './webuploader'
; 的方式引入 webuploader
,會報''caller', 'callee', and 'arguments' properties may not be accessed on strict mode ...'的錯, 這是因為你的babel使用了嚴格模式,而caller這些在嚴格模式下禁止使用。所以 可以直接在index.html
中引入webuploader.js
,或是手動去解決babel中'use strict'的問題。
基於webuploader封裝Vue元件
#封裝好的元件upload.vue如下,介面可以根據特定的業務進行擴充。
注意:功能和ui分離,此組成封裝好了基本的功能,沒有提供ui,ui在具體的頁面上去實現。
<template> <p class="upload"> </p> </template> <script> export default { name: 'vue-upload', props: { accept: { type: Object, default: null, }, // 上传地址 url: { type: String, default: '', }, // 上传最大数量 默认为100 fileNumLimit: { type: Number, default: 100, }, // 大小限制 默认2M fileSingleSizeLimit: { type: Number, default: 2048000, }, // 上传时传给后端的参数,一般为token,key等 formData: { type: Object, default: null }, // 生成formData中文件的key,下面只是个例子,具体哪种形式和后端商议 keyGenerator: { type: Function, default(file) { const currentTime = new Date().getTime(); const key = `${currentTime}.${file.name}`; return key; }, }, multiple: { type: Boolean, default: false, }, // 上传按钮ID uploadButton: { type: String, default: '', }, }, data() { return { uploader: null }; }, mounted() { this.initWebUpload(); }, methods: { initWebUpload() { this.uploader = WebUploader.create({ auto: true, // 选完文件后,是否自动上传 swf: '/static/lib/webuploader/Uploader.swf', // swf文件路径 server: this.url, // 文件接收服务端 pick: { id: this.uploadButton, // 选择文件的按钮 multiple: this.multiple, // 是否多文件上传 默认false label: '', }, accept: this.getAccept(this.accept), // 允许选择文件格式。 threads: 3, fileNumLimit: this.fileNumLimit, // 限制上传个数 //fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传图片的大小 formData: this.formData, // 上传所需参数 chunked: true, //分片上传 chunkSize: 2048000, //分片大小 duplicate: true, // 重复上传 }); // 当有文件被添加进队列的时候,添加到页面预览 this.uploader.on('fileQueued', (file) => { this.$emit('fileChange', file); }); this.uploader.on('uploadStart', (file) => { // 在这里可以准备好formData的数据 //this.uploader.options.formData.key = this.keyGenerator(file); }); // 文件上传过程中创建进度条实时显示。 this.uploader.on('uploadProgress', (file, percentage) => { this.$emit('progress', file, percentage); }); this.uploader.on('uploadSuccess', (file, response) => { this.$emit('success', file, response); }); this.uploader.on('uploadError', (file, reason) => { console.error(reason); this.$emit('uploadError', file, reason); }); this.uploader.on('error', (type) => { let errorMessage = ''; if (type === 'F_EXCEED_SIZE') { errorMessage = `文件大小不能超过${this.fileSingleSizeLimit / (1024 * 1000)}M`; } else if (type === 'Q_EXCEED_NUM_LIMIT') { errorMessage = '文件上传已达到最大上限数'; } else { errorMessage = `上传出错!请检查后重新上传!错误代码${type}`; } console.error(errorMessage); this.$emit('error', errorMessage); }); this.uploader.on('uploadComplete', (file, response) => { this.$emit('complete', file, response); }); }, upload(file) { this.uploader.upload(file); }, stop(file) { this.uploader.stop(file); }, // 取消并中断文件上传 cancelFile(file) { this.uploader.cancelFile(file); }, // 在队列中移除文件 removeFile(file, bool) { this.uploader.removeFile(file, bool); }, getAccept(accept) { switch (accept) { case 'text': return { title: 'Texts', exteensions: 'doc,docx,xls,xlsx,ppt,pptx,pdf,txt', mimeTypes: '.doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt' }; break; case 'video': return { title: 'Videos', exteensions: 'mp4', mimeTypes: '.mp4' }; break; case 'image': return { title: 'Images', exteensions: 'gif,jpg,jpeg,bmp,png', mimeTypes: '.gif,.jpg,.jpeg,.bmp,.png' }; break; default: return accept } }, }, }; </script> <style lang="scss"> // 直接把官方的css粘过来就行了 </style>
使用封裝好的上傳元件
#新頁面,使用範例如下:
ui需要自己去實作。大概的程式碼可以點這裡 。
<vue-upload ref="uploader" url="xxxxxx" uploadButton="#filePicker" multiple @fileChange="fileChange" @progress="onProgress" @success="onSuccess" ></vue-upload>
分片的原理及流程
#當我們上傳一個大檔案時,會被外掛分片,ajax請求如下:
1.多個upload請求都是分片的請求,把大檔案分成多個小份一次一次向伺服器傳遞
2.分片完成後,即upload完成後,需要向伺服器傳遞一個merge請求,讓伺服器將多個分片檔案合成一個檔案
分片
可以看到發起了多次upload 的請求,我們來看看upload 發送的特定參數:
第一個設定( content-disposition
)中的guid 和第二個設定中的access_token ,是我們透過webuploader配置裡的formData ,也就是傳遞給伺服器的參數
後面幾個設定是檔案內容,id、name、type、size等
其中chunks 為總分片數, chunk 為目前第幾分片。圖片中分別為12和9。當你看到chunk是11的upload請求時,代表這是最後一個upload請求了。
合併
分片後,檔案還未整合,資料大概是下面這個樣子:
#做完了分片後,其實工作還沒完,我們還要再發送個ajax請求給伺服器,告訴他把我們上傳的幾個分片合併成一個完整的檔案。
我怎麼知道分片上傳完了,我何時做合併?
webuploader
外掛程式有一個事件是 uploadSuccess
,包含兩個參數, file 和後台傳回的response ;當所有分片上傳完畢,該事件會被觸發,
我們可以透過伺服器傳回的欄位來判斷是否要做合併了。
例如後台回傳了 needMerge ,我們看到它是 true 的時候,就可以發送合併的請求了。
存在的已知問題
在做單一檔案暫停與繼續上傳時,發現了這個外掛程式的bug:
#1 、當設定的 threads>1
,使用單一檔案上傳功能,即stop方法傳入file時,會報錯誤Uncaught TypeError: Cannot read property 'file' of undefined
#出錯的原始碼如下:這是因為暫停時為了讓下一個檔案繼續傳輸,會將目前的pool池中pop掉暫停的檔案流。這裡做了循環,最後一次循環的時候,v是undefined的。
2、設定的threads為1,能正常暫停,但暫停後再繼續上傳是失敗的。
原理和上一個一樣,暫停時把當前檔案流在 pool 中全部 pop 了,當檔案開始 upload 的時候,會檢查當期 pool ,而此時已經沒有之前暫停的檔案流了。 上面是我整理給大家的,希望今後對大家有幫助。 ######相關文章:#########深入理解Node module模組#############利用Console來Debug的10個高階技巧總表###### #######關於vuejs中v-if和v-show的區別及v-show不起作用問題#######以上是透過Vue2.0結合webuploader如何實現檔案分片上傳功能(詳細教學)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver CS6
視覺化網頁開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!