ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

uni-app实现文件上传功能

2020-07-09 23:35:18  阅读:1084  来源: 互联网

标签:index url app xhr let file uni 上传


uni-app实现文件上传功能

目前找到的比较好用的一款第三方插件
文件上传插件地址 https://ext.dcloud.net.cn/plugin?id=1015
插件下载选择下载示例项目zip ,可以直接运行项目查看效果

目录结构如下
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20200317231930880.png?,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="../../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 = {}) => {
	console.log(`
	上传地址:${url}\n
	请求头:${JSON.stringify(header)}\n
	参数:${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

标签:index,url,app,xhr,let,file,uni,上传
来源: https://www.cnblogs.com/that-jay/p/13276926.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有