プロジェクトのシナリオ:
バイナリ ファイルをプレビューする必要がある小さなプログラムが開発されました。Android 側では正常にプレビューできますが、iOS 側ではファイルが破損しているというメッセージが表示され、ファイルをプレビューできません。
問題の説明
iOS 上の WeChat アプレットでファイルをプレビューすると、ファイルがプレビューできず、ファイルが破損していると表示されます。ただし、Android 側では、アプレットはファイルをプレビューできます。
原因分析:
バックエンド インターフェイスはバイナリ ファイル ストリーム データを返します。まず、uni.downloadFile() を呼び出してファイル ストリーム データをダウンロードし、次に uni.openDocument() を呼び出してファイルをプレビューします。コードは以下のように表示されます。
WeChat アプレット 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()で成功の戻り値を出力すると、バックエンド インターフェイスによって渡されたファイル タイプが docx であることがわかります。上の図に示すように、フロントエンドでのファイル ストリームの解析プロセス中に
、
, docx 形式のファイルは doc に解析され、Android ではプレビューの仕組みが iOS とは異なるため、iOS ではファイルを開くことができません。
解決:
ネット上で色々な方法を試しても問題は解決しません。そこで、公式プレビュー ファイル APIである uni.openDocument(OBJECT)から始めてみました
。 filePath は必須フィールドですが、fileType は必須ではありません。
WeChat アプレットは 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 file.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')
}
})
}
})
}
}
})