在微信小程序中保存網絡圖片

微信代碼片斷點這裏, 該功能須要添加appid才能進行正常的測試。javascript


在小程序的文檔中咱們得知,wx.saveImageToPhotosAlbum 是用來保存圖片到相冊的。html

可是仔細一看會發現這個接口的filePath參數只接受臨時文件路徑或永久文件路徑,不支持網絡圖片路徑,意味着咱們不能直接調用這個接口。。java

所以先須要把該文件下載至本地,使用 wx.downloadFilegit

但值得注意的是小程序只能夠跟指定的域名與進行網絡通訊,也就是說下載圖片以前,咱們須要先去微信公衆者平臺的開發設置裏設置uploadFile合法域名github

示例代碼以下:小程序

<!-- 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)
        }
      })
    });
  },
})

而後理論上就能夠保存圖片了... 用戶第一次在咱們的小程序使用保存圖片這個功能是會彈出一個受權彈框,若是用戶手滑點了拒絕受權後再點一次保存圖片,而後就會發現什麼反應都沒有了。。。api

出現這樣的緣由是由於這個受權彈框只會出現一次,因此咱們得想辦法再讓用戶從新受權一次。這時就想到使用 wx.authorize .promise

可是通過測試後發現,使用 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
    })
  }
})

最後這樣就完成啦~


https://anran758.github.io/bl...

相關文章
相關標籤/搜索