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

使用RNFetchBlob下载PDF报Download manager错误status code=16问询

问题原因排查

错误码16对应Android DownloadManager的ERROR_HTTP_DATA_ERROR,属于系统下载管理器层面的请求失败,Chrome可正常下载是因为两者的请求环境、权限配置、请求头参数存在差异,你的代码存在以下明确问题:

  • 路径拼接依赖的date、file_ext变量未定义,生成的下载路径非法,DownloadManager无法写入文件
  • Android高版本权限适配错误:Android 13及以上WRITE_EXTERNAL_STORAGE权限已废弃,申请该权限会直接返回拒绝,同时Android 10+分区存储规则限制了公共目录的写入逻辑
  • 未配置合法请求头:多数服务端会校验User-Agent、Accept等头信息,系统DownloadManager默认的请求头可能被服务端拦截
  • 未适配特殊场景:如果URL是HTTP明文协议、包含未转义的特殊字符、存在301/302重定向、需要携带鉴权信息(Cookie/Token),默认配置的DownloadManager都无法正常处理
可行解决方案

1. 基础配置修正

首先修改android/app/src/main/AndroidManifest.xml:

  • 在application节点添加android:requestLegacyExternalStorage="true",适配Android 10的分区存储过渡规则
  • 如果使用HTTP明文URL,添加网络安全配置允许明文流量,或直接改用HTTPS协议的URL

2. 权限逻辑修正

Android 11及以上下载文件到公共Download目录不需要申请存储权限,调整权限申请逻辑:

const checkPermission = async (FILE_URL) => {
  if (Platform.OS === 'ios') {
    downloadFile(FILE_URL);
    return;
  }
  // Android版本判断
  if (Platform.Version >= 33) {
    // Android13+无需申请存储权限直接下载
    downloadFile(FILE_URL);
  } else if (Platform.Version >= 29) {
    // Android10-12 申请存储权限
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
        {
          title: 'Storage Permission Required',
          message: 'Application needs access to your storage to download File',
        }
      );
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        downloadFile(FILE_URL);
      } else {
        Alert.alert('Error','Storage Permission Not Granted');
      }
    } catch (err) {
      console.warn(err);
    }
  } else {
    // 低版本安卓正常申请权限
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
        {
          title: 'Storage Permission Required',
          message: 'Application needs access to your storage to download File',
        }
      );
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        downloadFile(FILE_URL);
      } else {
        Alert.alert('Error','Storage Permission Not Granted');
      }
    } catch (err) {
      console.warn(err);
    }
  }
};

3. 下载逻辑修正

补全变量定义,添加请求头,改用公共Download目录避免路径权限问题:

const downloadFile = (FILE_URL) => {
  const { config, fs } = RNFetchBlob;
  // 改用公共Download目录,不需要额外权限
  let RootDir = fs.dirs.DownloadDir;
  // 补全缺失的date变量定义
  const date = new Date();
  // 补全PDF后缀,你也可以根据URL动态提取后缀
  const file_ext = '.pdf';
  let options = {
    fileCache: true,
    addAndroidDownloads: {
      path:
        RootDir +
        '/file_' + 
        Math.floor(date.getTime() + date.getSeconds() / 2) +
        file_ext,
      description: 'downloading file...',
      notification: true,
      useDownloadManager: true,
      // 允许媒体扫描,下载后可以在文件管理器看到
      mediaScannable: true,
      // 配置MIME类型为PDF
      mime: 'application/pdf'
    },
    // 添加请求头,模拟Chrome的UA避免被服务端拦截
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
      'Accept': 'application/pdf,*/*'
      // 如果需要鉴权,在这里添加Authorization或者Cookie头,比如:
      // 'Authorization': `Bearer ${你的Token}`
    }
  };
  config(options)
    .fetch('GET', FILE_URL)
    .then(res => {
      setDownloading(false);
      console.log('res -> ', JSON.stringify(res));
      alert('Téléchargement terminé');
    })
    .catch(err => {
      // 捕获异常方便排查
      console.error('下载失败:', err);
      setDownloading(false);
    });
};

4. 特殊场景处理

如果以上修改后仍报错,检查以下项:

  • 确认URL没有未转义的中文、特殊字符,如有需要先用encodeURI()转义
  • 如果URL存在301/302重定向,可先自行请求一次获取最终地址再传入下载
  • 如果是自签名HTTPS证书,可在config中添加trustAll: true允许所有证书

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:15:03