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


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 相关文章推荐
js每次Title显示不同的名言
Sep 25 Javascript
javascript 限制输入脚本大全
Nov 03 Javascript
jQuery.Validate 使用笔记(jQuery Validation范例 )
Jun 25 Javascript
jquery+css+ul模拟列表菜单具体实现思路
Apr 15 Javascript
获得Javascript对象属性个数的示例代码
Nov 21 Javascript
在页面加载完成后通过jquery给多个span赋值
May 21 Javascript
用模版生成HTML的的框架jquery.tmpl使用详解
Jan 07 Javascript
jQuery可见性过滤选择器用法示例
Sep 09 Javascript
通过原生JS实现为元素添加事件的方法
Nov 23 Javascript
JavaScript实现瀑布流以及加载效果
Feb 11 Javascript
微信小程序局部刷新触发整页刷新效果的实现代码
Nov 21 Javascript
浅谈JavaScript中this的指向更改
Jul 28 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
回首过去10年中最搞笑的10部动漫,哪一部让你节操尽碎?
2020/03/03 日漫
其他功能
2006/10/09 PHP
使用新浪微博API的OAuth认证发布微博实例
2015/03/27 PHP
php生成txt文件实例代码介绍
2016/04/28 PHP
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
jquery中$each()方法的使用指南
2015/04/30 Javascript
js实现瀑布流的三种方式比较
2020/06/28 Javascript
返回函数的JavaScript函数
2016/06/14 Javascript
前端构建工具之gulp的配置与搭建详解
2017/06/12 Javascript
JavaScript实现的超简单计算器功能示例
2017/12/23 Javascript
浅析node应用的timing-attack安全漏洞
2018/02/28 Javascript
解决eclipse中没有js代码提示的问题
2018/10/10 Javascript
你应该了解的JavaScript Array.map()五种用途小结
2018/11/14 Javascript
微信小程序-form表单提交代码实例
2019/04/29 Javascript
JS实现的简单tab切换功能完整示例
2019/06/20 Javascript
浅析Vue中拆分视图层代码的5点建议
2019/08/15 Javascript
element实现合并单元格通用方法
2019/11/13 Javascript
vue项目中播放rtmp视频文件流的方法
2020/09/17 Javascript
[19:59]2014DOTA2国际邀请赛 IG战队纪录片
2014/08/07 DOTA
对Python w和w+权限的区别详解
2019/01/23 Python
python交互界面的退出方法
2019/02/16 Python
对django中foreignkey的简单使用详解
2019/07/28 Python
python实现超市商品销售管理系统
2019/11/22 Python
Python flask框架实现浏览器点击自定义跳转页面
2020/06/04 Python
PyCharm 2020.2 安装详细教程
2020/09/25 Python
python利用proxybroker构建爬虫免费IP代理池的实现
2021/02/21 Python
HTML5和以前HTML4的区别整理
2013/10/20 HTML / CSS
C#中有没有运算符重载?能否使用指针?
2014/05/05 面试题
协议书模板
2014/04/23 职场文书
白岩松演讲
2014/05/21 职场文书
法务专员岗位职责
2015/02/14 职场文书
教师岗位说明书
2015/09/30 职场文书
导游词之新疆尼雅遗址
2019/10/16 职场文书
java协程框架quasar和kotlin中的协程对比分析
2022/02/24 Java/Android
未发现nvidia显卡怎么办?Win11系统中未检测到nvidia显卡解决教程
2022/04/08 数码科技
css弧边选项卡的项目实践
2023/05/07 HTML / CSS