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>
最后
-
如有不正之处,请佬不吝赐教,万分感谢。
-
祝大家向上!