您现在的位置是:首页 >技术杂谈 >react-native 文件上传的坑网站首页技术杂谈

react-native 文件上传的坑

头发茂盛男孩 2024-06-13 00:01:03
简介react-native 文件上传的坑

需求:

1.通过画布或者其他的获取图片插件生成base64

2.base64转换file上传文件

1.图片插件生成base64

生成base64,可以通过一些插件会给你生成,自己需要生成的话可以使用 ReaderFile的readAsDataURL()来转换

 var reader = new FileReader();
        reader.readAsDataURL(inpFile.files[0]);
        reader.onload = function () {
        baseData = reader.result;
        console.log("? ~ file: 图片:", baseData); //获取到base64格式图片
};

2.base64转换file

base64转换有多种方法,就不一一列出,直接上代码

import { Base64 } from 'js-base64'

/**
 * 将base64转换为文件
 * @param dataurl  base64编码
 * @param filename  file name
 * @returns
 */
export const dataURLtoFile = (base64Str: any, fileName: any) => {
  const arr = base64Str.split(',')
  const mime = arr[0].match(/:(.*?);/)[1] // base64解析出来的图片类型
  const bstr = Base64.dencode(arr[1]) // 对base64串进行操作,去掉url头,并转换为byte   atob为window内置方法
  let len = bstr.length
  const ab = new ArrayBuffer(len) // 将ASCII码小于0的转换为大于0
  const u8arr = new Uint8Array(ab) //

  while (len--) {
    u8arr[len] = bstr.charCodeAt(len)
  }
  // 创建新的 File 对象实例[utf-8内容,文件名称或者路径,[可选参数,type:文件中的内容mime类型]]
  return new File([u8arr], fileName, {
    type: mime,
  })
}

上面代码需要注意:针对base64解码,可以使用 atob() 方法来进行解码,但这是window方法,在react-native不起作用。可以使用 js-base64 插件来代替。

3.上传文件

上传接口根据自己接口来判断

    // result 是小编当前使用的签名插件 react-native-signature-capture 
    // 会返回参数 {encoded: base64编码, pathName: 文件路径}
  _onSaveEvent = async (result: any) => {
    const fd = new FormData()
    // base64转换file
    const file = dataURLtoFile(
      `data:image/png;base64,${result.encoded}`,
      `signature_${Date.now()}.png`,
    )
    fd.append('file', file)
    // 调用接口
    const dataFileUrl = await this.props.handleFileUrl(fd)
    const tokenUrl = await this.props.addSasTokenOnUrl(dataFileUrl.url)
    console.log('? ~ 上传文件 === ', dataFileUrl)
    console.log('? ~ 下载文件 === ', tokenUrl)

    ....
  }

4.上传报错

这个报错真的让我这个菜鸟头晕,但我经过三天三夜的战斗才发现一点问题,一点!!

在web使用new File()生成新的文件类型打印输出是没问题,但是在react-native输出出来的是类似于object的类型,所以导致文件上传缺失,不成功

解决方法:

生成新的文件类型并添加

    // result 是小编当前使用的签名插件 react-native-signature-capture 
    // 会返回参数 {encoded: base64编码, pathName: 文件路径}
  _onSaveEvent = async (result: any) => {
    // 文件类型
    const file = {
      uri: result.pathName,
      type: 'multipart/form-data',
      name: `signature_${Date.now()}.png`,
    }
    const fd = new FormData()
    // base64转换file
    // const file = dataURLtoFile(
    //   `data:image/png;base64,${result.encoded}`,
    //   `signature_${Date.now()}.png`,
    // )
    fd.append('file', file)
    // 调用接口
    const dataFileUrl = await this.props.handleFileUrl(fd)
    const tokenUrl = await this.props.addSasTokenOnUrl(dataFileUrl.url)
    console.log('? ~ 上传文件 === ', dataFileUrl)
    console.log('? ~ 下载文件 === ', tokenUrl)

    ....
  }

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。