安卓Android微信浏览器H5中保存图片

318 阅读3分钟

1.背景介绍

以下介绍均来自前端西瓜哥

  • 目前在手机微信浏览器中打开的 H5 页面,是无法通过 JavaScript 的 API 实现图片或文件下载的。

  • 为什么在手机的默认浏览器就可以下载,但我们在微信里面打开浏览器,就下不了了呢?

  • 推测是微信 APP 的权限问题,下载的权限是掌握在当前使用的 APP 手上的。微信拒绝了内置浏览器的下载文件请求,即使浏览器自身有对应的下载 API,但你就是下载不了。

  • 微信为什么这么做?是因为怕以前常见的浏览器弹窗广告一样的情况出现。如果对图片下载权限不做限制的话,很多搞营销的就会诱导用户打开一些网页,然后自动下载一些广告宣传图片之类的东西。

但长按图片保存还是可以的

  • 但也不是完全没办法,微信还是提供了一些 API 来实现 受限 的下载功能。

2.解决方法

以下解决方案均来自前端西瓜哥

  • 首先要判断浏览器是否为微信浏览器,如果不是微信浏览器,下载保持原来逻辑。

  • 如果是图片,点击下载按钮时弹出弹窗,提示用户长按图片下载;

  • 如果是视频或文档文件,提示用户使用默认浏览器去下载文件。考虑到用户用新的浏览器又要登陆很麻烦,引导用户点击右上角将链接用默认浏览器打开并不是好方案。

3.实现方法

3.1 安卓微信内置浏览器中

  • 我遇到的是安卓微信内置浏览器中不能保存海报图片。
  • 海报页面上方有海报背景图列表(用于切换海报底图的),页面下方是下载海报图片的按钮,我使用canvas把海报和二维码画在一起的,最后转为图片的,以上是我大概的视图,不能直接截图,只能口述。
  • 如果下载的资源是图片的话,可以使用长按下载,但是页面的元素记得有使用图片标签。
  • 长按下载,也可以引导用户去普通浏览器(自带浏览器等)下载。
    <template>
        <image id="saveImg" :src="img" />
    </template>
    
    <script setup>
        // #ifdef H5
        // 如果是在微信内置浏览器中,则提示用户 '请长按图片保存' 
        if (['WechatOfficialAccount'].includes(sheep.$platform.name)) {
          sheep.$helper.toast('请长按图片保存');
          return;
        }
        const base64 = painterImageUrl.value; // 是base64格式
        const arr = base64.split(',');
        const bytes = atob(arr[1]);
        let ab = new ArrayBuffer(bytes.length);
        let ia = new Uint8Array(ab);
        for (let i = 0; i < bytes.length; i++) {
          ia[i] = bytes.charCodeAt(i);
        }
        const blob = new Blob([ab], { type: 'application/octet-stream' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = new Date().valueOf() + ".png";
        const e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        a.dispatchEvent(e);
        URL.revokeObjectURL(url);
        // #endif
        
        // #ifndef H5
        uni.saveImageToPhotosAlbum({
          filePath: painterImageUrl.value, // 资源的临时地址
          success: (res) => {
            sheep.$helper.toast('保存成功');
          },
          fail: (err) => {
            sheep.$helper.toast('保存失败');
            console.log('图片保存失败:', err);
          },
          complete: () => {
            uni.hideLoading();
          }
        });
        // #endif
    </script>

最后

  • 如有不正之处,请佬不吝赐教,万分感谢。

  • 祝大家向上!