一、需求:项目是基于react框架实现的h5页面。其中 有一个按钮,要求实现 点击后 下载图片的功能。
测试时发现在网页端是可以正常下载,但是一旦内嵌到APP环境下,则会出现下载失败的情况。
二、原因:
1、首先,需要了解WebView是什么?
WebView是一个基于webkit引擎、展现web页面的控件。可以显示和渲染Web页面,与JS交互,也可以和原生代码交互。
App中内嵌的H5页面是WebView解析的。在Android手机中,网页的解析和显示网页的能力是由webkit内核实现的,webview在android SDK(原生)中被封装为一个叫做WebView组件,通过这个组件可以在app中显示html+css+js等相应的web页面,当然也就可以显示一个远程url,比如用它打开百度首页是可以的。可以理解为:android开发中的一个activity里使用了webview组件,并打开了一个html页面呈现给用户。
2、所以,当页面有下载功能的时候,点击上去是一点反应都没有的。原来就是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下载。
三、解决:
有两种方式,一种是修改为点击进行 图片预览的功能,然后通过长按图片 调用app内部的图片保存下载机制去让用户手动下载。
这里使用ant-mobile的ImageViewer组件,实现图片预览功能。
//state层
const [imageVisible, setImageVisible] = useState(false);
const [imageUrl, setImageUrl] = useState<string>('');
//html层
<div id="canvasImg" className={styles.cardWrapper}>
这里是需要保存成图片的内容
</div>
<Button
className={styles.mainButton}
block
shape='rounded'
color='primary'
onClick={()=> saveToImg() }
>
生成图片
</Button>
<ImageViewer
image={imageUrl}
visible={imageVisible}
onClose={() => {
setImageVisible(false)
}}
/>
//js层
function saveToImg() {
//点击预览的回调事件
const element: HTMLElement = document.getElementById('canvasImg') as HTMLElement; // 需要导出的页面
html2canvas(element, {
allowTaint: true,
useCORS: true,
}).then((canvas) => {
// imgUrl 是图片的 base64格式 代码 png 格式
const imgUrl = canvas.toDataURL('image/png');
//图片预览功能
setImageUrl(imgUrl);
if(imgUrl !== '') {
setImageVisible(true);
} else {
Toast.show({
icon: 'fail',
duration: 1000,
content: `暂不支持查看`,
});
}
});
}
第二种设置WebView的DownloadListener,实现自己的DownloadListener来实现文件的下载。