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

React Native WebView场景下下载zip文件的实现问题咨询

React Native WebView下载Aadhaar离线KYC zip文件解决方案

你之前直接调用API失败的核心原因是缺少WebView内的会话Cookie、请求头校验参数,该站点做了同源校验,直接请求会被拦截,可通过以下两种方案解决:

方案1:启用WebView原生下载回调+会话凭证同步

你注释的onFileDownload是安卓端的核心入口,iOS需要额外通过请求拦截处理,具体实现如下:

  • 修正WebView基础配置
<WebView
  source={{ uri: "https://resident.uidai.gov.in/offline-kyc" }}
  ref={webviewRef}
  renderLoading={LoadingIndicatorView}
  startInLoadingState={true}
  injectedJavaScript={runFirst}
  onMessage={onMessage}
  renderError={loadError}
  allowFileAccess={true}
  allowFileAccessFromFileURLs={true}
  javaScriptEnabled={true}
  domStorageEnabled={true}
  // 安卓端下载回调
  onFileDownload={async ({ nativeEvent: { downloadUrl } }) => {
    // 同步WebView当前会话Cookie,避免请求无权限
    const cookie = await webviewRef.current.injectJavaScript("document.cookie;");
    const userAgent = await webviewRef.current.injectJavaScript("navigator.userAgent;");
    downloadFile(downloadUrl, cookie, userAgent);
  }}
  // iOS端拦截下载请求
  shouldStartLoadWithRequest={(request) => {
    if (request.url.endsWith('.zip') || request.headers['Content-Type'] === 'application/zip') {
      downloadFile(request.url, request.headers['Cookie'], request.headers['User-Agent']);
      // 拦截下载请求,不让WebView默认处理
      return false;
    }
    return true;
  }}
/>
  • 实现文件下载逻辑,推荐搭配rn-fetch-blob处理文件写入,请求头保持和WebView一致,避免站点反爬拦截
import RNFetchBlob from 'rn-fetch-blob';

const downloadFile = async (url, cookie, userAgent) => {
  const { dirs } = RNFetchBlob.fs;
  const config = {
    fileCache: true,
    addAndroidDownloads : {
      useDownloadManager : true,
      notification : true,
      path: `${dirs.DownloadDir}/aadhaar_offline_kyc.zip`,
      description : 'Aadhaar离线KYC文件下载',
      mime: 'application/zip'
    },
    headers: {
      'Cookie': cookie,
      'Referer': 'https://resident.uidai.gov.in/offline-kyc',
      'User-Agent': userAgent
    }
  };
  RNFetchBlob.config(config)
    .fetch('GET', url)
    .then(res => {
      console.log('文件下载完成,路径:', res.path());
    })
    .catch(err => console.log('下载失败:', err));
}

方案2:注入JS监听Blob类型下载(适配iOS端blob流下载场景)

如果站点是通过JS生成Blob对象触发下载,没有公开的直链,可通过注入JS拦截下载行为,把Blob转成base64传给RN端写入本地:

  • 注入JS代码扩展原有的自动点击逻辑
const runFirst = `
  // 拦截a标签下载行为
  const originalClick = HTMLAnchorElement.prototype.click;
  HTMLAnchorElement.prototype.click = function() {
    if (this.download && this.href.includes('blob:')) {
      fetch(this.href)
        .then(res => res.blob())
        .then(blob => {
          const reader = new FileReader();
          reader.readAsDataURL(blob);
          reader.onloadend = () => {
            window.ReactNativeWebView.postMessage(JSON.stringify({
              type: 'download',
              data: reader.result,
              filename: this.download
            }));
          }
        })
      return;
    }
    originalClick.call(this);
  }
  // 原有自动点击提交按钮逻辑
  // ...
  true;
`;
  • 处理onMessage回调写入本地文件
const onMessage = (event) => {
  const data = JSON.parse(event.nativeEvent.data);
  if (data.type === 'download') {
    const base64Code = data.data.split(',')[1];
    RNFetchBlob.fs.writeFile(
      `${RNFetchBlob.fs.dirs.DownloadDir}/${data.filename}`,
      base64Code,
      'base64'
    ).then(() => console.log('文件写入成功'));
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:09:02