uni-app实现文件上传功能

【uni-app实现文件上传功能】赋料扬雄敌,诗看子建亲。这篇文章主要讲述uni-app实现文件上传功能相关的知识,希望能为你提供帮助。
uni-app实现文件上传功能
目前找到的比较好用的一款第三方插件
文件上传插件地址 https://ext.dcloud.net.cn/plugin?id=1015
插件下载选择下载示例项目zip,可以直接运行项目查看效果
目录结构如下
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200317231930880.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1c2VqaWVnZTY=,size_16,color_FFFFFF,t_70 =200x240)
index.vue,是使用文件上传功能的当前页面@up-success=" onSuccess" 是文件上传成功以后回传的数据

< template> < view> < l-file ref=" lFile" @up-success=" onSuccess" > < /l-file> < view class=" padding text-center" > < view class=" padding" > < button @tap=" onUpload" > 上传< /button> < /view> < /view> < /view> < /template> < script> import lFile from ‘@/components/l-file/l-file.vue‘ export default { components:{lFile}, data() { return { } }, methods: { /* 上传 */ onUpload() { this.$refs.lFile.upload({ // #ifdef APP-PLUS currentWebview: this.$mp.page.$getAppWebview(), // #endif //非真实地址,记得更换 url: ‘https://www.example.com/upload‘, //默认file,上传文件的key name: ‘uploadFile‘, // header: {‘Content-Type‘:‘类型‘,‘Authorization‘:‘token‘}, //...其他参数 }); }, onSuccess(res) { console.log(‘上传成功回调=====33====‘,JSON.stringify(res)); uni.showToast({ title: JSON.stringify(res), icon: ‘none‘ }) } } } < /script>


l-file.vue,是文件上传功能的封装组件,最后加载的是index.html文件wv.overrideUrlLoading监听返回的文件上传结果。
getRequest(url) { let theRequest = new Object(); let index = url.indexOf(" ?" ); if (index != -1) { let str = url.substring(index+1); let strs = str.split(" & " ); for(let i = 0; i < strs.length; i ++) { theRequest[strs[i].split(" =" )[0]]=unescape(strs[i].split(" =" )[1]); } } return theRequest; }, appChooseFile({currentWebview,url,name = ‘file‘,header,...formData} = {}) { // #ifdef APP-PLUS let wv = plus.webview.create(" " ," /hybrid/html/index.html" ,{ ‘uni-app‘: ‘none‘, //不加载uni-app渲染层框架,避免样式冲突 top: 0, height: ‘100%‘, background: ‘transparent‘ },{ url, header, key: name, ...formData, }); wv.loadURL(" /hybrid/html/index.html" ) currentWebview.append(wv); wv.overrideUrlLoading({mode:‘reject‘},(e)=> { let {fileName,id} = this.getRequest(e.url); return this.onCommit( this.$emit(‘up-success‘,{fileName,data: {id,statusCode: 200}}) ); }); // #endif }


index.html 源码
< !DOCTYPE html> < html lang=" zh-cn" > < head> < meta charset=" UTF-8" > < title class=" title" > [文件管理器]< /title> < meta name=" viewport" content=" width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> < style type=" text/css" > .content {background: transparent; } .fixed {position: fixed; bottom: 0; left: 0; right: 0; width: 100%; } .content .mask {top: 0; background: rgba(0,0,0,.4); z-index: 90; } .content .file-content {z-index: 91; height: 60px; background: #fff; text-align: center; } .btn {position: relative; } .btn .file {position: absolute; z-index: 93; left: 0; right: 0; top: 0; bottom: 0; height: 60px; width: 100%; opacity: 0; } .btn-bg {margin-top: 10px; background: #0066CC; color: #fff; width: 80%; height: 40px; border: 0; border-radius: 5px; } .tis {top: 0; z-index: 95; display: none; justify-content: center; align-items: center; } .tis .tis-content {background: #fff; width: 60%; border-radius: 10px; padding: 20px 0; } .tis .tis-content img {width: 50px; height: 50px; } .tis-progress {margin: 10px 0; color: #999; } .cancel-btn {margin-top: 30px; height: 30px; line-height: 1; padding: 0 2em; background: #e3e3e3; color: #898989; border: 0; border-radius: 5px; } < /style> < /head> < body> < div class=" content" > < div class=" fixed mask" > < /div> < div align=" center" class=" fixed tis" > < div class=" tis-content" > < div> < img src=https://www.songbingjia.com/android/static/logo.png" > < /div> < div class=" tis-progress" > 努力上传中.. < /div> < div class=" cancel" > < button type=" button" class=" cancel-btn" > 取消上传< /button> < /div> < /div> < /div> < div class=" fixed file-content" > < div class=" btn" > < button type=" button" class=" btn-bg" > 打开文件管理器< /button> < input class=" file" type=" file" /> < /div> < /div> < /div> < script type=" text/javascript" src=" https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js" > < /script> < script src=" js/h5-uploader.js" type=" text/javascript" charset=" utf-8" > < /script> < /body> < /html>


h5-uploader.js 源码负责h5代码上传文件及其进度展示,及上传结果回传
let mask = document.querySelector(" .mask" ); let fileDom = document.querySelector(" .file" ); let tis = document.querySelector(" .tis" ); let progress = document.querySelector(" .tis-progress" ); let cancel = document.querySelector(" .cancel-btn" ); let createUpload = (file, url, key=‘file‘, header = {},data = https://www.songbingjia.com/android/{}) => { console.log(` 上传地址:${url} 请求头:${JSON.stringify(header)} 参数:${JSON.stringify(data)} `); if (!url) {return; } tis.style.display = ‘flex‘; let formData = new FormData(); formData.append(key, file); for (let keys in data) { formData.append(keys, data[keys]); } let xhr = new XMLHttpRequest(); xhr.open(" POST" , url, true); for (let keys in header) { xhr.setRequestHeader(keys, header[keys]); } xhr.upload.addEventListener(" progress" , function(event) { if(event.lengthComputable){ let percent = Math.ceil(event.loaded * 100 / event.total) + " %" ; progress.innerText = `努力上传中..${percent}`; } }, false); xhr.ontimeout = function(){ // xhr请求超时事件处理 progress.innerText = ‘请求超时‘; setTimeout(()=> { tis.style.display = ‘none‘; plus.webview.currentWebview().close(); },1000); }; xhr.onreadystatechange = (ev) => {if(xhr.readyState == 4) { console.log(‘status:‘+xhr.status); if (xhr.status == 200) { progress.innerText = ‘上传成功‘; console.log(‘返回数据:‘+xhr.responseText); location.href = `callback?fileName=${file.name}& id=${xhr.responseText}`; } else { progress.innerText = ‘上传失败了‘; }setTimeout(()=> { tis.style.display = ‘none‘; plus.webview.currentWebview().close(); },1000); } }; xhr.send(formData); cancel.addEventListener(" click" , ()=> { xhr.abort(); plus.webview.currentWebview().close(); }); }mask.addEventListener(" click" , () => { plus.webview.currentWebview().close(); }); document.addEventListener(‘UniAppJSBridgeReady‘, () => { let {url,key,header,formData} = plus.webview.currentWebview(); fileDom.addEventListener(‘change‘, (event) => { let file = fileDom.files[0]; if(file.size > (1024*1024 * 10)) { plus.nativeUI.toast(‘单个文件不能超过10M,请重新上传‘); return; } console.log(file.name); createUpload(file, url, key,header,formData); }, false); });

插件地址 https://ext.dcloud.net.cn/plugin?id=1015







    推荐阅读