You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native WebView中Base64格式图片下载实现求助

解决WebView中Base64格式图片无法通过download标签下载的问题

WebView对data URI的download属性支持存在局限性,默认不会触发下载流程,需要通过平台端拦截处理或前端预处理来解决,以下是具体方案:

一、Android WebView 拦截处理

通过自定义下载监听器识别Base64链接,手动解码并写入本地文件:

webView.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> {
    if (url.startsWith("data:")) {
        // 拆分data URI结构
        String[] uriParts = url.split(",");
        String metaInfo = uriParts[0];
        String base64Content = uriParts[1];
        
        // 提取文件类型与后缀
        String mimeTypeFull = metaInfo.split(";")[0].replace("data:", "");
        String fileExt = mimeTypeFull.split("/")[1];
        
        // 解码Base64为字节流
        byte[] fileBytes = Base64.decode(base64Content, Base64.DEFAULT);
        
        // 写入本地下载目录
        File saveFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "download." + fileExt);
        try (FileOutputStream fos = new FileOutputStream(saveFile)) {
            fos.write(fileBytes);
            // 通知系统扫描文件,使其在相册/下载列表中可见
            MediaScannerConnection.scanFile(this, new String[]{saveFile.getAbsolutePath()}, null, null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {
        // 保留原有普通URL下载逻辑
    }
});

注意:需提前申请WRITE_EXTERNAL_STORAGE权限(Android 13+需申请READ_MEDIA_IMAGES等细分权限)。

二、iOS WKWebView 拦截处理

通过导航代理拦截data URI请求,解析后转为Data保存到本地:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let requestUrl = navigationAction.request.url, requestUrl.scheme == "data" else {
        decisionHandler(.allow)
        return
    }
    
    let uriComponents = requestUrl.absoluteString.split(separator: ",")
    guard uriComponents.count == 2, let metaSection = uriComponents.first, let base64Section = uriComponents.last else {
        decisionHandler(.allow)
        return
    }
    
    // 提取MIME类型与文件后缀
    let metaParts = metaSection.split(separator: ";")
    guard let mimeTypePart = metaParts.first, mimeTypePart.starts(with: "data:"),
          let fileExt = mimeTypePart.dropFirst(5).split(separator: "/").last else {
        decisionHandler(.allow)
        return
    }
    
    // 解码并保存文件
    if let fileData = Data(base64Encoded: String(base64Section)) {
        let docDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let saveUrl = docDir.appendingPathComponent("download.\(fileExt)")
        
        do {
            try fileData.write(to: saveUrl)
            // 可添加通知提示用户下载完成,或调用系统打开文件
        } catch {
            print("文件保存失败:\(error.localizedDescription)")
        }
    }
    
    decisionHandler(.cancel) // 取消原请求,避免WebView无效处理
}

注意:需在Info.plist中配置文件访问相关权限,若需共享文件到系统相册,还需额外处理相册写入权限。

三、前端通用预处理方案

通过JavaScript监听点击事件,将Base64转为Blob后触发下载,适配多平台WebView:

document.addEventListener('click', function(e) {
    const targetLink = e.target.closest('a');
    if (!targetLink || !targetLink.href.startsWith('data:')) return;
    
    e.preventDefault(); // 阻止默认下载行为
    
    // 解析data URI
    const [metaStr, base64Str] = targetLink.href.split(',');
    const mimeType = metaStr.split(';')[0].replace('data:', '');
    
    // Base64转Blob
    const byteChars = atob(base64Str);
    const byteNumbers = new Array(byteChars.length);
    for (let i = 0; i < byteChars.length; i++) {
        byteNumbers[i] = byteChars.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const fileBlob = new Blob([byteArray], { type: mimeType });
    
    // 创建临时URL触发下载
    const tempUrl = URL.createObjectURL(fileBlob);
    const downloadLink = document.createElement('a');
    downloadLink.href = tempUrl;
    downloadLink.download = targetLink.download || `download.${mimeType.split('/')[1]}`;
    document.body.appendChild(downloadLink);
    downloadLink.click();
    
    // 清理临时资源
    setTimeout(() => {
        URL.revokeObjectURL(tempUrl);
        document.body.removeChild(downloadLink);
    }, 100);
});

注意:需确保WebView开启JavaScript支持(Android需设置webSettings.setJavaScriptEnabled(true),iOS默认开启)。


内容的提问来源于stack exchange,提问作者rafiulah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 00:31:07