uni-app实现文件上传、下载、预览(非只图片和视频)

需求

在项目中要求在当前页面上传、下载和预览多种格式文件,需要兼容H5(在app中打开)、Android、IOS、微信小程序,文件类型包含word、excel、ppt、pdf、zip、rar、图片。

上传

第一步,肯定是先去翻uni-app的文档,期望着官方能够上传、下载、预览一条龙的包干了,调调api就行了。然而理想是丰满的,现实是残酷的。

既然要上传文件,那肯定要先选择到文件,先找找选取文件的api吧。看看我找到了什么:

  • uni.chooseImage从本地相册选择图片或使用相机拍照。
  • input组件 没有type=file

连选择文件都做不到,只能求助大佬了。出发吧,插件市场。

APP端上传(这里用插件)

在插件市场中,搜索到的插件基本都是只实现了APP端和微信小程序的,我选择了一个下载量最多的。
在这里插入图片描述
按照教程一步步来,更换一下上传地址,添加一下参数,果然可以了。至此已经解决了Android和IOS的上传。小程序上的我还没测试。
接下来就是H5的上传了

H5上传

因为产品的需求是在当前页面上传,那么久不用考虑web-view了。最后还是决定用的动态创建input file选择文件。

var input = document.createElement('input');
	input.type = 'file';
	this.$refs.input.$el.appendChild(input);
	input.onchange = () => {
		const file = input.files[0];
		if(!this.fileWhiteList.includes(getSuffix(file.name))){
			uni.showToast({
				title:'您选择的文件格式有误',
				icon:'none'
			})
			return false;
		}
		if(file.size>(1024*1024 * 50)){
			uni.showToast({
				title:'单个文件请勿超过50M,请重新上传',
				icon:'none'
			})
		}
		let formData = new FormData();
		formData.append('file', file);

至此,文件选择已经完成了。接下来就是上传了。找找uni-app的api。

1、uni.uploadFile

很好,uni-app中自带了一个上传的方法,这下上传应该是稳了,我们看看它的参数
在这里插入图片描述
what?只支持image、video、audio三种格式的文件,看来是白高兴一场了。
不过也没事,我可以通过网络请求传formData啊。开搞开搞…

2、uni.request

调用一下api,将选择好的文件传入formData,竟然报错
在这里插入图片描述
查看了request的文档才知道,它支持Object/String/ArrayBuffer类型的data。

那么request也不能用,那看看上面的插件是怎么做的上传呢,学习一下。原来是用的原生的XMLHttpRequest去做的。那就跟着大佬的脚步走吧,附上完整代码

var input = document.createElement('input');
input.type = 'file';
this.$refs.input.$el.appendChild(input);
input.onchange = () => {
	const file = input.files[0];
	if(!this.fileWhiteList.includes(getSuffix(file.name))){
		uni.showToast({
			title:'您选择的文件格式有误',
			icon:'none'
		})
		return false;
	}
	if(file.size>(1024*1024 * 50)){
		uni.showToast({
			title:'单个文件请勿超过50M,请重新上传',
			icon:'none'
		})
	}
	let formData = new FormData();
	formData.append('file', file);
	let xhr = new XMLHttpRequest();
	xhr.open("POST", '接口地址', true);
	xhr.setRequestHeader('登录授权参数', 'value');
	xhr.upload.addEventListener("progress", function(event) {
		if (event.lengthComputable) {
			let percent = Math.ceil(event.loaded * 100 / event.total) + "%";
			uni.showLoading({
				title:`努力上传中..${percent}`
			})
		}
	}, false);
	xhr.ontimeout = function() {
		// xhr请求超时事件处理
		uni.showToast({
			title:'请求超时'
		})
	};
	xhr.onreadystatechange = () => {
		if (xhr.readyState == 4) {
			console.log('status:' + xhr.status);
		
			if (xhr.status == 200) {
				uni.showToast({
					title:'上传成功'
				})
				const response=JSON.parse(xhr.responseText);
				if(responseChecker(response)){ // responseChecker是我自己的接口校验方法,
					this.$emit('upload',response.data) // 因为我是封装的组件,所以数据emit到父组件中
				}
			} else {
				uni.showToast({
					title:'上传失败'
				})
			}
		
		}
	};
	xhr.send(formData);
}
input.click()

至此文件上传已经完成了,接下来就是下载和预览了。

下载和预览

在uni-app的api中有uni.downloadFile和uni.saveFile可以将文件保存到本地,uni.openDocument可以打开文件。但是这三个api都不支持H5。那就先用两个方法先解决APP端的下载和预览。

uni.downloadFile({
	url: '接口地址',
	success: res => {
		let filePath = res.tempFilePath;
		if (open) { // open存在,代表预览操作
			let system = uni.getSystemInfoSync().platform;
			if (system == 'ios') {
				filePath = encodeURI(filePath);
			}
			uni.openDocument({
				filePath,
				success: () => {
					console.log('打开文档成功');
				},
				fail: error => {
					console.log(error)
				}
			});
		} else {  // open不存在,代表下载操作
			uni.saveFile({
				tempFilePath: filePath,
				success: () => {
					uni.showToast({
						title:'下载成功'
					})
				},
				fail:()=>{
					uni.showToast({
						title:'下载失败'
					})
				}
			})
		}
	},
	fail:()=>{
		if(!open){
			uni.showToast({
				title:'下载失败'
			})
		}
	}
})

APP端的下载完全就是调用api了,没什么问题了。下面开始H5的下载和预览,我使用的是a标签download。

Android上的app内访问

一开始我调用的下载接口,后端返回的是文件的二进制流,在PC端测试的时候是可以下载的,但是一放到app中访问就不行。

const res=await downloadFile(参数);
const blob = new Blob([res]);
const tempLink = document.createElement('a');
tempLink.href = URL.createObjectURL(blob);
tempLink.setAttribute('download', name);
tempLink.click();

后来就去查了一下,原来在Android环境app的webview中是不支持a标签下载blob的。


const tempLink = document.createElement('a');
tempLink.href = '下载地址';
tempLink.setAttribute('download', name);
tempLink.click();

ok,让后端同事提供一个get请求的接口,直接返回文件,再试一下。

这下文件直接打开了,去文件管理器中查找了一下,发现图片是没有保存下来的,而其他offce文件确实下载下来了。
office文件是下载
图片提示手动保存
再到IOS试一下,发现也是一样的。因为技术有限,也就只能做到这个程度了,最后与产品协商后,在APP端显示下载、预览按钮,在H5端只显示预览按钮。

至此,uni-app中文件上传、下载、预览的功能大部分的实现了,如果大佬们有什么好的方案,请不吝赐教,也欢迎指正文中不正确的地方。

  • 22
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
本课程讲了Vue3+Vue2+Uni-app(uniapp)入门基础与实战,其中还重点讲解了ES6、TypeScript这些基础知识,实战由两大价值5000元的真实企业级项目组成,分别是仿京东电商网站和仿美团微信点餐小程序,同时两大项目代码全部赠送,还赠送前后端架构模板,工作中直接使用。VUEuni-app是目前热门的前端框架,本课程教你如何快速学会VUEuni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件和插件,正式上线白屏问题,性能优化、解决iphoneX“刘海”兼容性问题、微信支付、微信授权登录,获取位置在地图上显示,获取用户所在的城市和街道信息,微信小程序发布审核等。对正在工作当中或打算学习VUEuni-app高薪就业的你来说,那么这门课程便是你手中的葵花宝典。学习技巧:学习当中不要只看,一定要多敲代码,如果碰到某一个知识点不是很明白,不要钻牛角尖,千万不要因为一个点,放弃整个森林,接着往下学,硬着头皮开发项目。只要能亲自开发一个完整的项目,你会发现不明白的地方自然而然就明白了,项目做出来就真正的学会了。此vueuni-app课程以面试和实战为基础进行讲解,每个知识点都会让你知道在实际项目开发中如何使用,学习后,可以开发大型项目,增强逻辑思维,至少让你拥有3年以上开发经验的实力!代码和ppt均可下载!免费提供《企业级完整实战项目接口文档》,绝对可用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值