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

如何解决Google Drive API+Axios+RNFS下载图片无法打开的问题?

问题描述

通过Google Drive API的files:get方法下载图片,并用RNFS保存到指定路径。Postman验证API响应正确,但保存后的.jpg文件无法打开。已尝试调整RNFS的encoding参数(base64/binary)和GET请求参数,均无效。

现有代码

Axios下载代码

downloadActivityCard: async function (id) {
    try {
      const params = {
        //  fields: 'kind,driveId,mimeType,id,name,teamDriveId,thumbnailLink,webContentLink,modifiedTime',
        alt: 'media',
        responseType: 'arraybuffer',
      };
      const dirPath = MAINDIRECTORY + '/FeaturedActivityCards/' + id;
      const filePath = `${dirPath}/cardImage.jpg`;
      let card = {};

      //check if file exists
      if (await checkFileExists(filePath)) {
        throw new Error('This Activity Card is already downloaded');
      }

      //set up the get URL, then call axios for response
      const downloadUrl =
        DRIVE_API_URLS.SEARCH_FILES +
        '/' +
        id +
        DRIVE_API_URLS.SEARCH_PARAMETERS;

      const response = await axios.get(downloadUrl, { params }).catch(error => {
        console.error('ERROR IN DOWNLOADING ACTIVITY CARD: ' + error);
      });

      card = response.data;
      //make directory for the newly downloaded card, write the card into this path and return
      await makeDirectory(dirPath);
      await writeFile(true, filePath, card);
      return filePath;
    } catch (e) {
      console.log('ERROR IN DOWNLOADING ACTIVITY CARD: ' + e);
    }
  }

RNFS写入代码

export async function writeFile(isImage, filepath, content) {
  const options = {
    encoding: '',
  };
  if (isImage) {
    options.encoding = 'base64';
  } else {
    options.encoding = 'utf8';
  }
  return RNFS.writeFile(filepath, content, options.encoding)
    .then(success => {
      console.log(`FILE WRITTEN!: ${filepath}`);
    })
    .catch(err => {
      console.log(`RNFS writeFile: ${err.message}`);
    });
}
解决方案

问题核心是二进制数据处理不匹配:axios请求设置responseType: 'arraybuffer'后返回ArrayBuffer类型数据,但RNFS的writeFile在指定base64编码时,需要传入base64字符串而非原始二进制数据。以下两种修改方式任选其一即可:

方式一:将ArrayBuffer转为base64字符串后写入

修改Axios请求后的处理逻辑,把原始二进制数据转成base64格式:

// 替换原`card = response.data;`这一行
const buffer = Buffer.from(response.data);
card = buffer.toString('base64');

RNFS的writeFile函数保持base64编码设置不变,即可正确写入图片。

方式二:直接写入二进制数据

RNFS支持直接写入二进制数据,无需转base64,修改以下两处:

  1. 调整Axios的responseType为blob:
const params = {
  alt: 'media',
  responseType: 'blob', // 改为blob类型
};
  1. 更新RNFS的writeFile函数,适配二进制数据写入:
export async function writeFile(isImage, filepath, content) {
  let encoding = 'utf8';
  if (isImage) {
    encoding = 'binary'; // 图片使用binary编码
    // 若响应是Blob类型,先转为Buffer
    if (content instanceof Blob) {
      const arrayBuffer = await content.arrayBuffer();
      content = Buffer.from(arrayBuffer);
    }
  }
  return RNFS.writeFile(filepath, content, encoding)
    .then(success => {
      console.log(`FILE WRITTEN!: ${filepath}`);
    })
    .catch(err => {
      console.log(`RNFS writeFile: ${err.message}`);
    });
}

额外优化:统一错误处理

移除Axios请求后的.catch链,利用外层try/catch统一捕获错误,避免response为undefined的情况:

// 修改原response获取代码
const response = await axios.get(downloadUrl, { params });
// 去掉后面的.catch(error => {...})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:00:36