解决基于uniapp的微信小程序,在iOS端无法预览文件,提示文件已损坏问题

项目场景:

开发了一个小程序,有预览二进制文件的需求。Android端可以成功预览,但iOS端提示文件已损坏,无法预览文件。

问题描述

微信小程序iOS端预览文件,显示无法预览此文件,文件已损坏。但是在Android端,小程序可以预览文件。

在这里插入图片描述


原因分析:

后端接口返回的是二进制文件流数据,首先调用uni.downloadFile()下载文件流数据,再调用uni.openDocument()预览文件。代码如下。
微信小程序 android端可以成功预览文件

				uni.downloadFile({
    
    
					url:'获取文件的接口地址',
					header: {
    
    
						AuthcToken: 'Bearer ' + uni.getStorageSync('mtoken'),
						responseType: 'blob',
					},
					complete() {
    
    
						uni.hideLoading();
					},
					fail(result) {
    
    
						uni.showToast({
    
    
							title: '下载文件失败',
							icon: 'none'
						})
					},
					success: function(res) {
    
    
						console.log(res,'文件地址')
						if (res.statusCode == 200) {
    
    
							var filePath = res.tempFilePath;
							uni.openDocument({
    
    
								filePath:filePath,
								success() {
    
    
									console.log(123456)
								}
							})
						} else {
    
    
							uni.showToast({
    
    
								title: '加载文件失败',
								icon: 'none'
							})
						}
					}
				});

此时,Android端已经可以成功预览文件了,但是在iOS端预览文件就显示文件损坏无法预览。
打印uni.downLoadFile()中success的返回值可以看到
在这里插入图片描述
后端接口传递的文件类型为docx,由上图表明,前端解析文件流的过程中,将docx格式的文件解析成了doc,又由于Andorid与iOS的预览机制不一样,导致文件在iOS端打不开。

解决方案:

经过尝试网上的多种方法,均无法解决该问题。于是我试着从官方预览文件api
入手,uni.openDocument(OBJECT),filePath是必传字段,但是fileType非必传。
在这里插入图片描述
微信小程序 android端 ios端均可成功预览文件

				uni.downloadFile({
    
    
					url:'获取文件的接口地址',
					header: {
    
    
						AuthcToken: 'Bearer ' + uni.getStorageSync('mtoken'),
						responseType: 'blob',
					},
					complete() {
    
    
						uni.hideLoading();
					},
					fail(result) {
    
    
						uni.showToast({
    
    
							title: '下载文件失败',
							icon: 'none'
						})
					},
					success: function(res) {
    
    
						console.log(res,'文件地址')
						if (res.statusCode == 200) {
    
    
							var filePath = res.tempFilePath;
							uni.openDocument({
    
    
								filePath:filePath,
								fileType:'docx', //指定文件类型为后端接口返回的文件类型
								success() {
    
    
									console.log(123456)
								}
							})
						} else {
    
    
							uni.showToast({
    
    
								title: '加载文件失败',
								icon: 'none'
							})
						}
					}
				});

指定uni.openDocument(),中的fileType为后端接口中返回的文件类型后缀名,即可在iOS端成功预览文件。

其他解决方法+指定文件名称

由于使用uni.downLoadFile()接口成功之后返回的路径,是临时的随机路径与名称,如果要指定文件名称,比如 (CSDN文件.docx),可以参考如下方法

				let filePath=`${
    
    wx.env.USER_DATA_PATH}/CSDN文件.doc`;
				 //使用原生方法获取二进制文件
				wx.request({
    
    
					url:'获取文件的接口地址',
					header:{
    
    
						AuthcToken: 'Bearer ' + uni.getStorageSync('mtoken'),
						Authorization: 'Bearer ' + uni.getStorageSync('mtoken'),
					},
					responseType:'arraybuffer',
					success(res) {
    
    
						console.log(res,'获取二进制文件')
						if(res.statusCode==200){
    
    
							const fs=wx.getFileSystemManager(); //全局的文件管理器
							// 写入文件
							fs.writeFile({
    
    
								filePath:filePath,
								data:res.data,//将返回的二进制文件流数据写入文件
								encoding:'binary',
								success(file){
    
    
									wx.openDocument({
    
    
										filePath:filePath,
										showMenu:true,
										fileType:'docx', //需要指定文件类型,否则iOS端无法预览
										success(success) {
    
    
											console.log('open success')
										},
										fail(err){
    
    
											console.log('open err')
										}
									})
								}
							})
						}
					}
				})

猜你喜欢

转载自blog.csdn.net/weixin_44132277/article/details/129792457
今日推荐