webuploader分片上傳的實(shí)現(xiàn)代碼(前后端分離)
本文介紹了webuploader分片上傳的實(shí)現(xiàn)代碼(前后端分離),分享給大家,具體如下:
WebUploader是由Baidu WebFE(FEX)團(tuán)隊(duì)開發(fā)的一個(gè)簡(jiǎn)單的以HTML5為主,F(xiàn)LASH為輔的現(xiàn)代文件上傳組件。在現(xiàn)代的瀏覽器里面能充分發(fā)揮HTML5的優(yōu)勢(shì),同時(shí)又不摒棄主流IE瀏覽器,沿用原來的FLASH運(yùn)行時(shí),兼容IE6+,iOS 6+, android 4+。兩套運(yùn)行時(shí),同樣的調(diào)用方式,可供用戶任意選用。采用大文件分片并發(fā)上傳,極大的提高了文件上傳效率。(這個(gè)是從官網(wǎng)上直接copy的解釋)
功能描述
1、webuploader是百度研發(fā)的上傳組件,文檔不是特別規(guī)整,但是也夠用了。
2、前端使用官網(wǎng)的上傳圖片demo,在此基礎(chǔ)上代碼略微調(diào)整做分片。既可以上傳圖片也可以上傳文件。文件超過分片大小才啟用分片。
3、分片上傳已做md5校驗(yàn),達(dá)到秒傳的效果。分片以后需要合并,可以先分片后合并,也可以邊分片邊合并,本示例采用的是邊分片邊合并的方案。
4、后端用springboot做框架搭建。springMVC做rest服務(wù),開啟跨域訪問。
5、容器用springboot內(nèi)置的tomcat插件,運(yùn)行Application的main方法即可啟動(dòng)服務(wù);
顯示效果
關(guān)鍵代碼前端
WebUploader.Uploader.register({ 'name': 'webUploaderHookCommand', 'before-send-file': 'beforeSendFile', "before-send": "beforeSend" }, { beforeSendFile: function(file) { var task = new WebUploader.Deferred(); fileName = file.name; fileSize = file.size; (new WebUploader.Uploader()).md5File(file, 0, 10 * 1024 * 1024).progress(function(percentage) {}).then(function(val) { fileMd5 = val; var url = checkUrl; var data = { type: 0, fileName: fileName, fileMd5: fileMd5, fileSize: fileSize }; $.ajax({ type: "POST", url: url, data: data, cache: false, async: false, // 同步 timeout: 1000, // todo 超時(shí)的話,只能認(rèn)為該分片未上傳過 dataType: "json", error: function(XMLHttpRequest, textStatus, errorThrown) { file.statusText = 'server_error'; task.reject(); } }).then(function(data, textStatus, jqXHR) { if(data.rtn == 0) { if(data.obj == 1) { file.statusText = 'file_existed'; task.reject(); } else { task.resolve(); } } else { task.reject(); } }); }); return task.promise(); }, beforeSend: function(block) { var task = new WebUploader.Deferred(); var url = checkUrl; var data = { type: 1, fileName: fileName, fileMd5: fileMd5, chunk: block.chunk, fileSize: block.end - block.start }; $.ajax({ type: "POST", url: url, data: data, cache: false, async: false, // 同步 timeout: 1000, // todo 超時(shí)的話,只能認(rèn)為該分片未上傳過 dataType: "json" }).then(function(data, textStatus, jqXHR) { if(data.rtn == 0 && data.obj == 1) { task.reject(); // 分片存在,則跳過上傳 } else { task.resolve(); } }); this.owner.options.formData.fileMd5 = fileMd5; this.owner.options.formData.chunkSize = chunkSize; return task.promise(); } }); // 實(shí)例化 uploader = WebUploader.create({ pick: { id: '#filePicker', label: '點(diǎn)擊選擇文件' }, formData: { uid: 123 }, dnd: '#dndArea', //指定文件拖拽的區(qū)域 paste: '#uploader', //指定監(jiān)聽paste事件的容器,如果不指定,不啟用此功能。此功能為通過粘貼來添加截屏的圖片。建議設(shè)置為document.body. swf: '../plugins/webuploader/Uploader.swf', chunked: true, chunkSize: chunkSize, chunkRetry: false, threads: 1, server: uploadUrl, // runtimeOrder: 'flash', // accept: { // title: 'Images', // extensions: 'gif,jpg,jpeg,bmp,png', // mimeTypes: 'image/*' // }, // 禁掉全局的拖拽功能。這樣不會(huì)出現(xiàn)圖片拖進(jìn)頁面的時(shí)候,把圖片打開。 disableGlobalDnd: true, fileNumLimit: 300 //限制多文件上傳的個(gè)數(shù) //fileSizeLimit: 200 * 1024 * 1024, // 限制所有文件的大小 200 M //fileSingleSizeLimit: 50 * 1024 * 1024 // 限制單個(gè)文件的大小 50 M });
后端
import java.io.File; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import com.bear.upload.util.FileUtil; import com.bear.upload.util.RETURN; import com.bear.upload.vo.CheckMd5FileVO; import com.bear.upload.vo.UploadVO; @Service public class ChunkUploadService { private static Logger LOG = LoggerFactory.getLogger(ChunkUploadService.class); @Value("${file.upload.path}") private String UPLOAD_PATH; private static final String Delimiter = "-"; /** * 上傳之前校驗(yàn)(整個(gè)文件、分片) * * @param md5FileVO * @return */ public Object check(CheckMd5FileVO md5FileVO) { Integer type = md5FileVO.getType(); Long chunk = md5FileVO.getChunk(); String fileName = md5FileVO.getFileName(); Long fileSize = md5FileVO.getFileSize(); if (type == 0) {// 未分片校驗(yàn) String destfilePath = UPLOAD_PATH + File.separator + fileName; File destFile = new File(destfilePath); if (destFile.exists() && destFile.length() == fileSize) { return RETURN.success("文件已存在,跳過", 1); } else { return RETURN.success("文件不存在", 0); } } else {// 分片校驗(yàn) String fileMd5 = md5FileVO.getFileMd5(); String destFileDir = UPLOAD_PATH + File.separator + fileMd5; String destFileName = chunk + Delimiter + fileName; String destFilePath = destFileDir + File.separator + destFileName; File destFile = new File(destFilePath); if (destFile.exists() && destFile.length() == fileSize) { return RETURN.success("分片已存在,跳過", 1); } else { return RETURN.success("分片不存在", 0); } } } /** * 文件上傳 * * @param file * @param uploadVO * @param appVersion * @return */ public Object upload(MultipartFile file, UploadVO uploadVO) { Long chunk = uploadVO.getChunk(); if (chunk == null) {// 沒有分片 return UnChunkUpload(file, uploadVO); } else {// 分片 return ChunkUpload(file, uploadVO); } } /** * 分片上傳 * * @param file * @param uploadVO * @param appVersion * @return */ public Object ChunkUpload(MultipartFile file, UploadVO uploadVO) { String fileName = uploadVO.getName(); String fileMd5 = uploadVO.getFileMd5(); Long chunk = uploadVO.getChunk();// 當(dāng)前片 Long chunks = uploadVO.getChunks();// 總共多少片 // 分片目錄創(chuàng)建 String chunkDirPath = UPLOAD_PATH + File.separator + fileMd5; File chunkDir = new File(chunkDirPath); if (!chunkDir.exists()) { chunkDir.mkdirs(); } // 分片文件上傳 String chunkFileName = chunk + Delimiter + fileName; String chunkFilePath = chunkDir + File.separator + chunkFileName; File chunkFile = new File(chunkFilePath); try { file.transferTo(chunkFile); } catch (Exception e) { LOG.error("分片上傳出錯(cuò)", e); return RETURN.fail("分片上傳出錯(cuò)", 1); } // 合并分片 Long chunkSize = uploadVO.getChunkSize(); long seek = chunkSize * chunk; String destFilePath = UPLOAD_PATH + File.separator + fileName; File destFile = new File(destFilePath); if (chunkFile.length() > 0) { try { FileUtil.randomAccessFile(chunkFile, destFile, seek); } catch (IOException e) { LOG.error("分片{}合并失敗:{}", chunkFile.getName(), e.getMessage()); return RETURN.fail("分片合并失敗", 1); } } if (chunk == chunks - 1) { // 刪除分片文件夾 FileUtil.deleteDirectory(chunkDirPath); return RETURN.success("上傳成功", 1); } else { return RETURN.fail("上傳中...", 1); } } /** * 未分片上傳 * * @param file * @param uploadVO * @param appVersion * @return */ public Object UnChunkUpload(MultipartFile file, UploadVO uploadVO) { String fileName = uploadVO.getName(); // String fileMd5 = uploadVO.getFileMd5(); // 文件上傳 File destFile = new File(UPLOAD_PATH + File.separator + fileName); if (file != null && !file.isEmpty()) { // 上傳目錄 File fileDir = new File(UPLOAD_PATH); if (!fileDir.exists()) { fileDir.mkdirs(); } if (destFile.exists()) { destFile.delete(); } try { file.transferTo(destFile); return RETURN.success("上傳成功", 0); } catch (Exception e) { LOG.error("文件上傳出錯(cuò)", e); return RETURN.fail("文件上傳出錯(cuò)", 0); } } return RETURN.fail("上傳失敗", 0); } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 關(guān)于webuploader插件使用過程遇到的小問題
- 推薦三款不錯(cuò)的圖片壓縮上傳插件(webuploader、localResizeIMG4、LUploader)
- 百度多文件異步上傳控件webuploader基本用法解析
- 使用WebUploader實(shí)現(xiàn)上傳文件功能(一)
- 快速掌握jQuery插件WebUploader文件上傳
- webuploader 實(shí)現(xiàn)圖片批量上傳功能附實(shí)例代碼
- webuploader實(shí)現(xiàn)上傳圖片到服務(wù)器功能
- webuploader模態(tài)框ueditor顯示問題解決方法
- 使用WebUploader實(shí)現(xiàn)分片斷點(diǎn)上傳文件功能(二)
- php + WebUploader實(shí)現(xiàn)圖片批量上傳功能
相關(guān)文章
VSCode開發(fā)TypeScript的實(shí)現(xiàn)步驟
本文主要介紹了VSCode開發(fā)TypeScript的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02JavaScript中的this關(guān)鍵字使用方法總結(jié)
這篇文章主要介紹了JavaScript中的this關(guān)鍵字使用方法總結(jié),本文講解了作為對(duì)象方法調(diào)用、作為函數(shù)調(diào)用、作為構(gòu)造函數(shù)調(diào)用、使用 apply 或 call 調(diào)用等內(nèi)容,需要的朋友可以參考下2015-03-03使用JavaScript italics方法實(shí)現(xiàn)文本變斜體教程示例
這篇文章主要為大家介紹了JavaScript italics實(shí)現(xiàn)文本變斜體教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12七個(gè)基于JavaScript實(shí)現(xiàn)的情人節(jié)表白特效
情人節(jié)將至 程序員證明自己不是直男的時(shí)候到啦 我們也有自己的專屬代碼浪漫。本文將介紹七個(gè)利用JavaScript實(shí)現(xiàn)的情人節(jié)表白特效,需要的可以參考一下2022-01-01詳解MVC如何使用開源分頁插件(shenniu.pager.js)
本文主要分享了shenniu.pager.js整個(gè)插件內(nèi)容,不多且清晰。具有很好的參考價(jià)值,需要的朋友一起來看下吧2016-12-12在IE6下發(fā)生Internet Explorer cannot open the Internet site錯(cuò)誤
最近在IE6下面時(shí)常會(huì)發(fā)生“Internet Explorer cannot open the Internet site ”錯(cuò)誤。2010-06-06強(qiáng)大的JavaScript響應(yīng)式圖表Chartist.js的使用
本篇文章主要介紹了強(qiáng)大的JavaScript響應(yīng)式圖表Chartist.js的使用,具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09JS實(shí)現(xiàn)點(diǎn)擊文本框改變背景顏色
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)點(diǎn)擊文本框改變背景顏色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08