WeChat 小程序下载文件实现

最近写小程序,要求实现下载功能,和之前web的下载还是有些不同的。主要区别来自于图标的下载,非图片文件下载的时候,可以直接预览后,再决定是否转发到好友或者在其他app中打开,而图片下载的时候,无法直接在微信中预览,只能直接下载到系统相册。

  • 具体代码:
js 复制代码
async downloadHandler(file) {  
  // file: url 文件超链接地址, name 文件名, type 文件类型
  if (!file.url) return;  
  uni.showLoading({  
   title: "请稍候",  
   mask: true  
  });  
  const { url:downloadPath, type, name:fileName } = file; 
  const that = this  
  const fileSavePath = `${wx.env.USER_DATA_PATH}/${fileName}`; // 组建文件存放的系统缓存临时地址
  console.log('fileSavePath', fileSavePath);  
  console.log("file type", type);
  uni.request({  
   url: downloadPath,  
   method: 'GET',  
   responseType: "arraybuffer",  
   timeout: 30000  
  }).then((res) => {  
   console.log('download', res);  // 根据文件超链接地址,获取文件二进制数据
   const fs = uni.getFileSystemManager();  // 获取系统文件管理对象 fs
   fs.writeFile({  
    filePath: fileSavePath,  
    data: res[1]?.data,  
    encoding: 'binary',  
    success() {  // 把文件二进制数据写入到系统缓存临时地址
     if (type === 'image') {  
      // 如果是图片格式,无法直接在微信预览,只能把图片下载到系统相册中。  
      that.savaImage(fileSavePath);
     } else {  
      // 如果是非图片格式,则可以在微信中直接预览文件,并后续转发和下载。  
      uni.openDocument({  
       filePath: fileSavePath,  
       showMenu: true  
      });  
      uni.hideLoading();  
     }  
    },  
    fail: (err) => {  
     console.log('writeFile err', err);  
     uni.showToast({  
      title: "保存文件出错",  
      icon: "none",  
      duration: 2000  
     });  
     uni.hideLoading();  
    }  
   })  
  }).catch((err) => {  
   console.log('download err', err);  
   uni.showToast({  
    title: "下载文件出错",  
    icon: "none",  
    duration: 2000  
   });  
   uni.hideLoading();  
  })  
},
savaImage(imgaPath) {  
  //获取用户是否有相册权限  
  const that = this  
  uni.getSetting({  
   success: (res) => {  
    if (!res.authSetting["scope.writePhotosAlbum"]) {  
     // 无相册权限时 发起相册权限请求  
     uni.authorize({  
      scope: "scope.writePhotosAlbum",  
      success: () => {  
       // 授权成功保存图片到系统相册  
       that.savaSysImagePath(imgaPath)  
      },  
      fail: () => {  
       // 授权失败  
       uni.hideLoading();  
       uni.showModal({  
        title: '您已拒绝获取相册权限',  
        content: '是否进入权限管理,调整授权?',  
        success: (res) => {  
         if (res.confirm) {  
          uni.openSetting({  
           success: (res) => {  
            console.log(res.authSetting);  
           }  
          })  
         } else if (res.cancel) {  
          uni.showToast({  
           title: "已取消获取相册权限",  
           icon: "none",  
           duration: 2000  
          });  
         }  
        }  
       })  
      }  
     })  
    } else {  
     // 有相册权限直接保存  
     that.savaSysImagePath(imgaPath)  
    }  
   },  
   fail: (err) => {  
    console.log('fail', err);  
    uni.showToast({  
     title: "获取相册权限出错",  
     icon: "none",  
     duration: 2000  
    });  
    uni.hideLoading();  
   }  
  })  
},
savaSysImagePath(imgaPath) {  
  uni.saveImageToPhotosAlbum({  
   filePath: imgaPath,  // 保存图片到系统相册,只能接受图片的系统缓存临时保存地址,而不是图片的超链接地址。
   success: () => {  
    uni.hideLoading();  
    uni.showToast({  
     title: "已保存图片到相册中!",  
     icon: "none",  
     duration: 2000  
    });  
   },  
   fail: (err) => {  
    console.log('fail', err);  
    uni.hideLoading();  
    uni.showToast({  
     title: err.errMsg,  
     icon: "none",  
     duration: 2000  
    })  
   },  
   complete: () => {  
    uni.hideLoading();  
   }  
  })  
}

以上就是下载图片和其他文件的方法。但是实际使用中发现,如果下载图片到系统相册,再转发朋友的时候,还得从相册中寻找图片,非常不方便,而且其实图片更多是为了转发给好友,其次才是保存到系统相册,并不需要总是下载到相册,这样还特别占用相册内存,非常不友好,如果图片也能像其他文件一样可以预览,然后再决定转发好友还是下载到相册就好了,于是发现uni 还提供了,一个图片预览的功能,uni.previewImage。

  • 代码改造为:
js 复制代码
onImgPreview(url) {  
  console.log('onImgPreview start', url)  
  uni.previewImage({  
   urls: [url],  // 可以直接接受图片的超链接地址。
   longPressActions: {  
    itemList: ['发送给朋友', '保存图片', '收藏'],  
    success: (data) => {  
     console.log('success', data);  
    },  
    fail: (err) => {  
     console.log('fail', err);  
    }  
   }  
  })  
},
async downloadHandler(file) {  
  // file: url 文件超链接地址, name 文件名, type 文件类型
  if (!file.url) return;  
  uni.showLoading({  
   title: "请稍候",  
   mask: true  
  });  
  const { url:downloadPath, type, name:fileName } = file; 
  const fileSavePath = `${wx.env.USER_DATA_PATH}/${fileName}`; // 组建文件存放的系统缓存临时地址
  console.log('fileSavePath', fileSavePath);  
  console.log("file type", type);  
     if (type === 'image') {  
       // 如果是图片可以直接预览,然后长按下载/转发/收藏,无需再设置一个下载按钮,把图片下载到系统相册。  
       this.onImgPreview(downloadPath);  // 无需把超链接转化为二进制数据,而是可以直接使用超链接地址,进行预览。
       return;  
     }  
  uni.request({  
   url: downloadPath,  
   method: 'GET',  
   responseType: "arraybuffer",  
   timeout: 30000  
  }).then((res) => {  
   console.log('download', res);  // 根据文件超链接地址,获取文件二进制数据
   const fs = uni.getFileSystemManager();  // 获取系统文件管理对象 fs
   fs.writeFile({  
    filePath: fileSavePath,  
    data: res[1]?.data,  
    encoding: 'binary',  
    success() {  // 把文件二进制数据写入到系统缓存临时地址 
      // 如果是非图片格式,则可以在微信中直接预览文件,并后续转发和下载。  
      uni.openDocument({  
       filePath: fileSavePath,  
       showMenu: true  
      });  
      uni.hideLoading(); 
    },  
    fail: (err) => {  
     console.log('writeFile err', err);  
     uni.showToast({  
      title: "保存文件出错",  
      icon: "none",  
      duration: 2000  
     });  
     uni.hideLoading();  
    }  
   })  
  }).catch((err) => {  
   console.log('download err', err);  
   uni.showToast({  
    title: "下载文件出错",  
    icon: "none",  
    duration: 2000  
   });  
   uni.hideLoading();  
  })  
}

并且uni.previewImage,这个预览功能,可以直接接受超链接地址,都无需缓存到本地系统临时文件中,这样既可以直接转发好友,也可以保存到相册,无需先下载到系统相册,然后再进入相册转发给好友,效果非常好。

相关推荐
头发还在的女程序员4 小时前
基于 Spring Boot + Vue 3 + uni-app 的灵活用工系统:四端架构与业务流程设计
vue.js·spring boot·uni-app·灵活用工·灵工系统
计算机毕设定制辅导-无忧学长20 小时前
《基于微信小程序的居家医疗陪护预约系统设计与实现》
java·spring boot·微信小程序·uniapp·居家医疗陪护预约系统
大数据技术派2 天前
我用AI写代码,做了3个小玩意儿
后端·微信小程序
Dumbness2 天前
订阅消息弹窗必须在用户点击里调:联调实验室里 timing 和 Mock 支付通知踩的坑
javascript·uni-app
律宏阔3 天前
Taro 4 项目从 npm 迁移到 pnpm 踩坑实录
前端·微信小程序·taro
码间留白3 天前
uni-app 鸿蒙离线打包:一个改动从源码到真机要穿过几条链
uni-app·鸿蒙·deveco·离线打包·uts插件
多客:duokelijie4 天前
代练订单系统选型思路:跨品类游戏接入、订单分层管理、自动结算逻辑拆解!
数据库·mysql·微信小程序·前端框架·uni-app·php·持续部署
码间留白4 天前
鸿蒙端对接 BLE 血压计:从一次握手到读数入库(二)设备篇
物联网·uni-app·鸿蒙·蓝牙ble·血压计
计算机毕设定制辅导-无忧学长5 天前
《基于微信小程序健康习惯激励系统设计与实现》
java·spring boot·mysql·微信小程序·uniapp·健康习惯激励系统
华玥作者5 天前
Vue 3 + TypeScript + uni-app 组件库推荐:hy-app(华玥组件库)
vue.js·typescript·uni-app