在微信小程序中保存网络图片


Posted in Javascript onFebruary 12, 2019

微信代码片段点这里, 该功能需要添加appid才能进行正常的测试。

在小程序的文档中我们得知,wx.saveImageToPhotosAlbum 是用来保存图片到相册的。

但是仔细一看会发现这个接口的filePath参数只接受临时文件路径或永久文件路径,不支持网络图片路径,意味着我们不能直接调用这个接口。。

因此先需要把该文件下载至本地,使用 wx.downloadFile 。

但值得注意的是小程序只可以跟指定的域名与进行网络通信,也就是说下载图片之前,我们需要先去微信公众者平台的开发设置里设置uploadFile合法域名。

示例代码如下:

<!-- index.wxml -->
<image class="qr-code" src="{{url}}" mode="aspectFill" />
<button class="text" bindtap="saveImage">保存图片</button>
// index.js
const app = getApp()

Page({
 data: {
  url: 'https://avatars3.githubusercontent.com/u/23024075?s=460&v=4'
 },

 // 保存图片
 saveImage() {
  this.wxToPromise('downloadFile', {
    url: this.data.url
   })
   .then(res => this.wxToPromise('saveImageToPhotosAlbum', {
    filePath: res.tempFilePath
   }))
   .then(res => {
    // do something
    wx.showToast({ title: '保存成功~',icon: 'none' });
   })
   .catch(err) => {
    console.log(err);

    // 如果是用户自己取消的话保存图片的话
    // if (~err.errMsg.indexOf('cancel')) return;
   })
 },

 /**
  * 将 callback 转为易读的 promise
  * @returns [promise]
  */
 wxToPromise(method, opt) {
  return new Promise((resolve, reject) => {
   wx[method]({
    ...opt,
    success(res) {
     opt.success && opt.success();
     resolve(res)
    },
    fail(err) {
     opt.fail && opt.fail();
     reject(err)
    }
   })
  });
 },
})

然后理论上就可以保存图片了... 用户第一次在我们的小程序使用保存图片这个功能是会弹出一个授权弹框,如果用户手滑点了拒绝授权后再点一次保存图片,然后就会发现什么反应都没有了。。。

出现这样的原因是因为这个授权弹框只会出现一次,所以我们得想办法再让用户重新授权一次。这时就想到使用 wx.authorize .

但是经过测试后发现,使用 wx.authorize 后,会报 authorize:fail auth deny 的错误。然后经过查阅资料得知:

  • 如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口;
  • 如果用户已授权,可以直接调用接口;
  • 如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景。

emmm... 那这样效果当然不符合我们预期,只能在换一种方式。这时就想到了使用<button open-type="openSetting"/>,在交互上做一个提示弹框,引导用户重新授权:

<image class="qr-code" src="{{url}}" mode="aspectFill" />
<button class="text" bindtap="saveImage">保存图片</button>

<!-- 简陋版提示 -->
<view wx:if="{{showDialog}}" class="dialog-wrap">
 <view class="dialog">
  这是一段提示用户授权的提示语
  <view class="dialog-footer">
   <button
    class="btn"
    open-type="openSetting"
    bindtap="confirm" >
     授权
   </button>
   <button class="btn" bindtap="cancel">取消</button>
  </view>
 </view>
</view>
const app = getApp()

Page({
 data: {
  url: 'https://avatars3.githubusercontent.com/u/23024075?s=460&v=4',
  showDialog: false,
 },

 saveImage() {
  this.wxToPromise('downloadFile', {
    url: this.data.url
   })
   .then(res => this.wxToPromise('saveImageToPhotosAlbum', {
    filePath: res.tempFilePath
   }))
   .then(res => {
    console.log(res);
    // this.hide();
    wx.showToast({
     title: '保存成功~',
     icon: 'none',
    });
   })
   .catch(({ errMsg }) => {
    console.log(errMsg)
    // if (~errMsg.indexOf('cancel')) return;
    if (!~errMsg.indexOf('auth')) {
     wx.showToast({ title: '图片保存失败,稍后再试', icon: 'none' });
    } else {
     // 调用授权提示弹框
     this.setData({
      showDialog: true
     })
    };
   })
 },

 // callback to promise
 wxToPromise(method, opt) {
  return new Promise((resolve, reject) => {
   wx[method]({
    ...opt,
    success(res) {
     opt.success && opt.success();
     resolve(res)
    },
    fail(err) {
     opt.fail && opt.fail();
     reject(err)
    }
   })
  });
 },

 confirm() {
  this.setData({
   showDialog:false
  })
 },

 cancel() {
  this.setData({
   showDialog: false
  })
 }
})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
让 JavaScript 轻松支持函数重载 (Part 2 - 实现)
Aug 04 Javascript
对象无length属性时IE6/IE7中无法将其转换成伪数组(ArrayLike)
Jul 31 Javascript
js+html+css实现鼠标移动div实例
Jan 30 Javascript
Iframe实现跨浏览器自适应高度解决方法
Sep 02 Javascript
简介JavaScript中的setHours()方法的使用
Jun 11 Javascript
js实现对ajax请求面向对象的封装
Jan 08 Javascript
谈一谈js中的执行环境及作用域
Mar 30 Javascript
js实现文字截断功能
Sep 14 Javascript
JS瀑布流实现方法实例分析
Dec 19 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
May 02 Javascript
xmlplus组件设计系列之图标(ICON)(1)
May 05 Javascript
Selenium执行Javascript脚本参数及返回值过程详解
Apr 01 Javascript
VUE中使用MUI方法
Feb 12 #Javascript
如何利用ES6进行Promise封装总结
Feb 11 #Javascript
在vue项目中引入vue-beauty操作方法
Feb 11 #Javascript
Vue表单控件绑定图文详解
Feb 11 #Javascript
图文讲解vue的v-if使用方法
Feb 11 #Javascript
ES6 如何改变JS内置行为的代理与反射
Feb 11 #Javascript
ES6 更易于继承的类语法的使用
Feb 11 #Javascript
You might like
基于PHPExcel的常用方法总结
2013/06/13 PHP
php实现对象克隆的方法
2015/06/20 PHP
WordPress开发中的get_post_custom()函数使用解析
2016/01/04 PHP
PHP的PDO预定义常量讲解
2019/01/24 PHP
小议Javascript中的this指针
2010/03/18 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
2013/02/02 Javascript
js获取当前日期代码适用于网页头部
2013/06/27 Javascript
javascript手工制作悬浮菜单
2015/02/12 Javascript
ClearTimeout消除闪动实例代码
2016/02/29 Javascript
基于jquery实现最简单的选项卡切换效果
2016/05/08 Javascript
JQuery 传送中文乱码问题的简单解决办法
2016/05/24 Javascript
webpack-dev-server远程访问配置方法
2018/02/22 Javascript
微信小程序scroll-x失效的完美解决方法
2018/07/18 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【凹多边形的分离轴检测算法】
2018/12/13 Javascript
解决vue 表格table列求和的问题
2019/11/06 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
google广告之另类js调用实现代码
2020/08/22 Javascript
VUE : vue-cli中去掉路由中的井号#操作
2020/09/04 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
Python与shell的3种交互方式介绍
2015/04/11 Python
python 根据pid杀死相应进程的方法
2017/01/16 Python
python pandas模块基础学习详解
2019/07/03 Python
使用Python实现图像标记点的坐标输出功能
2019/08/14 Python
Python对接 xray 和微信实现自动告警
2019/09/17 Python
Pytorch 之修改Tensor部分值方式
2019/12/27 Python
Django+RestFramework API接口及接口文档并返回json数据操作
2020/07/12 Python
Python Request类源码实现方法及原理解析
2020/08/17 Python
详解css3 Transition属性(平滑过渡菜单栏案例)
2017/09/05 HTML / CSS
C语言面试题
2015/10/30 面试题
建筑设计所实习生自我鉴定
2013/09/25 职场文书
求职信范文怎么写
2014/01/29 职场文书
优秀经理获奖感言
2014/03/04 职场文书
乡镇创先争优活动总结
2014/08/28 职场文书
就业推荐表导师评语
2014/12/31 职场文书
暑假生活随笔
2015/08/15 职场文书
CSS3 实现NES游戏机的示例代码
2021/04/21 HTML / CSS