Solve the problem that the WeChat applet based on uniapp cannot preview the file on the iOS side and prompts that the file is damaged

Project scenario:

A small program was developed with the need to preview binary files. The Android side can preview successfully, but the iOS side prompts that the file is damaged and cannot preview the file.

Problem Description

When previewing a file on the WeChat applet on iOS, it shows that the file cannot be previewed and the file is damaged. But on the Android side, the applet can preview files.

Insert image description here


Cause Analysis:

The backend interface returns binary file stream data. First, call uni.downloadFile() to download the file stream data, and then call uni.openDocument() to preview the file. code show as below.
WeChat applet Android can successfully preview files

				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'
							})
						}
					}
				});

At this point, the file can be previewed successfully on the Android side, but when previewing the file on the iOS side, it shows that the file is damaged and cannot be previewed.
Printing the return value of success in uni.downLoadFile(), you can see that
Insert image description here
the file type passed by the back-end interface is docx. As shown in the above figure, during the process of parsing the file stream at the front-end, the file in docx format is parsed into doc, and because of the Android The preview mechanism is different from that of iOS, so the file cannot be opened on iOS.

solution:

After trying various methods online, the problem cannot be solved. So I tried to start with the official preview file api
, uni.openDocument(OBJECT). filePath is a required field, but fileType is not required.
Insert image description here
WeChat applet can successfully preview files on both Android and iOS devices

				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'
							})
						}
					}
				});

Specify uni.openDocument(), where the fileType is the file type suffix returned in the backend interface, and the file can be successfully previewed on the iOS side.

Other solutions + specify file name

Since the path returned after successfully using the uni.downLoadFile() interface is a temporary random path and name, if you want to specify a file name, such as (CSDN file.docx), you can refer to the following method

				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')
										}
									})
								}
							})
						}
					}
				})

Guess you like

Origin blog.csdn.net/weixin_44132277/article/details/129792457