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


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 相关文章推荐
用jscript实现新建和保存一个word文档
Jun 15 Javascript
JS模拟面向对象全解(一、类型及传递)
Jul 13 Javascript
JS简单设置下拉选择框默认值的方法
Aug 20 Javascript
详解Javascript函数声明与递归调用
Oct 22 Javascript
jQuery实现 上升、下降、删除、添加一行代码
Mar 06 Javascript
基于BootStrap的前端分页带省略号和上下页效果
May 18 Javascript
easyui-datagrid开发实践(总结)
Aug 02 Javascript
angular2 ng2 @input和@output理解及示例
Oct 10 Javascript
JavaScript设计模式之代理模式简单实例教程
Jul 03 Javascript
Vue 实现前进刷新后退不刷新的效果
Jun 14 Javascript
使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码
Nov 01 Javascript
JavaScript实现省市区三级联动
Feb 13 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
linux php mysql数据库备份实现代码
2009/03/10 PHP
php cache类代码(php数据缓存类)
2010/04/15 PHP
php的array_multisort()使用方法介绍
2012/05/16 PHP
解析PHP缓存函数的使用说明
2013/05/10 PHP
微信公众平台天气预报功能开发
2014/07/06 PHP
php从csv文件读取数据并输出到网页的方法
2015/03/14 PHP
写给想学习Javascript的朋友一点学习经验小结
2010/11/23 Javascript
js操作textarea方法集合封装(兼容IE,firefox)
2011/02/22 Javascript
使用js+jquery实现无限极联动
2013/05/23 Javascript
JS模拟自动点击的简单实例
2013/08/08 Javascript
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
2014/12/18 NodeJs
14款经典网页图片和文字特效的jQuery插件-前端开发必备
2015/08/25 Javascript
JavaScript实现标题栏文字轮播效果代码
2015/10/24 Javascript
EasyUI学习之Combobox下拉列表(1)
2016/12/29 Javascript
jQuery验证表单格式的使用方法
2017/01/10 Javascript
nodejs 实现钉钉ISV接入的加密解密方法
2017/01/16 NodeJs
JavaScript实现图片本地预览功能【不用上传至服务器】
2017/09/20 Javascript
JavaScript实现鼠标滚轮控制页面图片切换功能示例
2017/10/14 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
MockJs结合json-server模拟后台数据
2020/08/26 Javascript
[02:28]DOTA2英雄基础教程 灰烬之灵
2013/12/19 DOTA
Python 时间处理datetime实例
2008/09/06 Python
利用Python破解斗地主残局详解
2017/06/30 Python
python中logging包的使用总结
2018/02/28 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
使用pycharm设置控制台不换行的操作方法
2019/01/19 Python
详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本
2019/02/25 Python
python的reverse函数翻转结果为None的问题
2020/05/11 Python
python动态规划算法实例详解
2020/11/22 Python
css3旋转木马_动力节点Java学院整理
2017/07/12 HTML / CSS
21岁生日感言
2014/02/27 职场文书
项目施工员岗位职责
2014/03/09 职场文书
文明之星事迹材料
2014/05/09 职场文书
学会用Python实现滑雪小游戏,再也不用去北海道啦
2021/05/20 Python
详解PHP用mb_string处理windows中文字符
2021/05/26 PHP
golang定时器
2022/04/14 Golang