微信小程序接收二进制流文件(图片预览,文件打开)

文章讲述了在处理通过downloadOaFile接口获取的二进制流时,必须设置uni.request的responseType为arraybuffer以避免文件损坏。res.data需要转换为arraybuffer才能正确写入文件,使用fs.writeFile完成文件写入,并根据文件扩展名决定用uni.previewImage预览图片还是wx.openDocument打开文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 下面通过downloadOaFile接口获取到二进制流,即res.data

注意!!!直接用downloadOaFile获取的二进制流文件在写入时会导致文件损坏,必须在uni.request对象的属性中加上

uni.request({responseType: 'arraybuffer',...}) 

如果不加,默认是

responseType: 'text'

这一点非常重要,踩了好久的坑,而且这两点的区别在network的response中还看不出来,因为两者的res.data看上去都是二进制流

注:arraybuffer是js内置的类,用于操作二进制文件,和blob差不多,所以我感觉也可以将res.data转成arraybuffer,之后再用fs.write写入

下面是转为的arraybuffer的方案,但是由于没试过,我也不知道能不能成功

const textEncoder = new TextEncoder();
const arrayBuffer = textEncoder.encode(data).buffer;

const arrayBuffer是一个arrayBuffer对象,用buffer方法得到的

注:arraybuffer也可以通过new出来,它就是一段连续的内存空间,但是很神奇居然可以用变量申请内存大小如下

const arrayBuffer = new ArrayBuffer(len)//len可以是变量

但是不能直接操作arraybuffer,必须再arraybuffer上建立视图,从而进行写入和释放内存操作

const dataView = new DataView(arraybuffer);

参考`ArrayBuffer`对象到底是什么 简单读懂 - 掘金

接着用getFileSystemManager将二进制流写成文件

const fs = uni.getFileSystemManager(); //获取全局唯一的文件管理器

fs.writeFile({...})//将二进制流写成文件

 最后通过文件扩展名判断用uni.previewImage或者wx.openDocument这两个api打开图片还是文件

完整代码如下

        let filePath = wx.env.USER_DATA_PATH + "/"+item.storageFileName;
        console.log(1111111111,item)
        downloadOaFile({
          filePath:item.storageFileName,
          fileName:item.storageFileName,
        }).then(res=>{
          const fs = uni.getFileSystemManager(); //获取全局唯一的文件管理器
          // fs.access({
          //   path: wx.env.USER_DATA_PATH,
          //   success: function(res) {
          //     console.log("临时文件目录已存在",res);
          //   },
          //   fail: function(err) {
          //     console.log("临时文件目录不存在,现在创建目录",err);
          //     fs.mkdir({
          //       dirPath: wx.env.USER_DATA_PATH,
          //       recursive: true,
          //       success: function(res) {
          //         console.log("创建目录成功",res);
          //       },
          //       fail: function(err) {
          //         console.log("创建目录失败",err);
          //       }
          //     });
          //   }
          // })
          console.log(filePath)
          console.log(typeof filePath)


          fs.writeFile({ // 写文件
            filePath: filePath, // wx.env.USER_DATA_PATH 指定临时文件存入的路径,后面字符串自定义
            data: res.data,
            encoding: "binary", //二进制流文件必须是 binary
            success (res){
              let imgExtName = ['png','jpg']
              console.log("成功写入文件",res)
              if (imgExtName.indexOf(item.extname)>-1){
                uni.previewImage({
                  current:item.storageFileName,
                  urls:[filePath],
                  success: function (res) {
                    console.log("成功打开图片",res)
                    console.log(filePath)

                    // setTimeout(()=>{wx.hideLoading()},500)
                  },
                  fail(res){
                    console.log("失败打开图片",res);
                  }
                })
              }else{

                wx.openDocument({ // 新开页面打开文档
                  fileType:item.extname,
                  filePath: filePath,  //拿上面存入的文件路径
                  success: function (res) {
                    console.log("成功打开文件")
                    // setTimeout(()=>{wx.hideLoading()},500)
                  },
                  fail(res){
                    console.log("失败打开文件",res)
                  }
                })
              }

            },
            fail(res){
              console.log("写文件失败",res)
            }
        })
      })

### 实现微信小程序中解码并打开Base64格式的文件微信小程序环境中处理Base64编码的数据,特别是当涉及到文件操作时,通常需要先将Base64字符串转换成二进制数据流,再根据具体的文件类型进行相应的展示或保存。由于微信小程序自带API并不直接支持Base64到Blob对象的转换,因此这部分功能需自行实现。 #### 解码Base64字符串至ArrayBuffer 为了能够正确解析Base64编码的内容,可以编写一段JavaScript函数来完成这一过程: ```javascript function base64ToArrayBuffer(base64) { var binaryString = window.atob(base64); var len = binaryString.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes.buffer; } ``` 这段代码定义了一个`base64ToArrayBuffer`方法用于接收Base64编码串作为输入,并返回对应的ArrayBuffer实例[^1]。 #### 使用wx.downloadFile下载并显示图片或其他类型的文件 对于图像类文件,在获取到了ArrayBuffer之后可以直接利用`<image>`组件加载;而对于文档等其他形式,则可能需要借助于临时路径的方式让用户查看。这里给出一个简单的例子说明如何通过`wx.downloadFile()`接口配合上述提到的方法来预览一张由Base64表示的照片: ```javascript // 假设已有一个名为base64ImageStr 的变量存储着Base64编码后的照片信息 const tempFilePath = wx.env.USER_DATA_PATH + '/temp.jpg'; let arrayBuffer = base64ToArrayBuffer(base64ImageStr); wx.saveFile({ tempFilePath: 'data:image/jpeg;base64,' + btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer))), success(res){ console.log('Saved file:', res.savedFilePath); // 更新页面上的img标签src属性指向新创建好的本地缓存地址 this.setData({imageUrl:res.savedFilePath}); }, fail(err){ console.error('Failed to save image', err); } }) ``` 需要注意的是,上面的例子仅适用于JPEG格式的小型图片文件。如果目标是PDF或者其他非多媒体资源,则应当考虑调用微信内置浏览器控件或是第三方插件来进行渲染[^2]。 另外值得注意的一点是在实际开发过程中可能会遇到跨域资源共享(CORS)的问题,这取决于服务器端设置以及所使用的网络请求方式。确保服务端配置允许来自微信小程序环境下的访问权限是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值