一、需求:项目是基于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来实现文件的下载。