目录

最近react-native项目上需要做文件上传下载的功能,由于才接触react-native不久,好多东西不熟悉,前期花了不少时间去探索,在此记录下探索后的成果

文件上传

1.文件选择

文件上传前需要选择相应的文件,可以使用第三方库react-native-file-selector来选择文件,以下是安卓和IOS上的交互效果
\"android上的效果图\"
\"ios上的效果图\"
引入react-native-file-selector,该库的详细使用方式查看官方文档

npm i -S react-native-file-selector
react-native react-native-file-selector

注意:

  1. react-native-file-selector在 后在android上可能会有些问题,需要手动 ,可以看官方的android手动
  2. 如果android上启动项目报错Execution failed for task \':app:transformDexArchiveWithDexMergerForDebug\',则需添加如下设置到android/app/build.gradle文件,找到defaultConfig添加multiDexEnabled true,问题原因(需FQ)

    defaultConfig {
            applicationId \"com.saaspartclubapp\"
            minSdkVersion 16
            targetSdkVersion 27
            versionCode 1
            versionName \"1.0\"
            ndk {
                abiFilters \"armeabi-v7a\", \"x86\"
            }
            multiDexEnabled true //添加这行代码
            vectorDrawables.useSupportLibrary = true
        }

官方使用的示例,最终拿到文件的路径,通过文件路径就可以进行文件上传操作了

RNFileSelector.Show(
    {
         : \'Select File\',
        onDone: (path) => {
            console.log(\'file selected: \' + path)
        },
        onCancel: () => {
            console.log(\'cancelled\')
        }
    }
)

2.文件上传

1.FormData对象包装

可以通过FormData来进行文件上传,在上一步已经获取到文件的路径,由此可以包装到FormData对象中,以下是示例代码

let formData = new FormData()
// file是字段名,根据后端接受参数的名字来定,android上通过react-native-file-selector获取的path是不包含\'file://\'协议的,android上需要拼接协议为\'file://\'+path,而IOS则不需要,type可以是文件的MIME类型或者\'multipart/form-data\'
formData.append(\'file\',{uri:\'file://\'+path,type:\'multipart/form-data\'})
...// 可能还会有其他参数 formData.append(key,value)

关于MIME类型

包装好FormData对象后,就可以进行文件上传了,下面将介绍多种上传的方式

2.上传示例

原生AJAX示例

let  Http = new  HttpRequest()
 Http.open(\'post\', url)
 Http.  = (err) => { \'error\', err }
 Http.  = () => {
  if ( Http.readyState == 4 &&  Http.status == 200) {
    console.log(\'res\',  Http.response)
  }
}
 Http.setRequestHeader(\'Content-Type\', \'multipart/form-data\')
 Http.send(formData)

fetch示例

fetch(url, {
  method: \'post\',
  headers: {
    \'Content-Type\': \'multipart/form-data\'
  },
  body: formData
}).then(res => {
  console.log(\'res\', res)
}).catch(err => {
  console.log(\'err\', err)
})

axios示例

axios.post(url, formData, {
  method: \'post\',
  headers: {
    \'Content-Type\': \'multipart/form-data\'
  }
}).then(res => {
  console.log(\'res\', res)
}).catch(err => {
  console.log(\'err\', err)
})

第三方库rn-fetch-blob

rn-fetch-blob是一个优秀的第三方react-native库,它支持多种形式的文件上传、文件下载以及对文件的读写操作,本文只会简单介绍该库的使用

以下只是简单的示例,详细示例可以查看文档,还有配置查看上传进程

RNFetchBlob.fetch(\'POST\', url, {
  // header...
  \'Content-Type\': \'multipart/form-data\'
}, [
    // path是指文件的路径,wrap方法可以根据文件路径获取到文件信息
    { name: \'avatar-foo\', filename: \'avatar-foo.png\', type: \'image/foo\', data: RNFetchBlob.wrap(path) },
    //... 可能还会有其他非文件字段{name:\'字段名\',data:\'对应值\'}
  ]).then((res) => {
    console.log(\'res\', res)
  }).catch((err) => {
    console.log(\'err\', err)
  })

文件下载

移动端应用跟浏览器环境有点不同,下载文件时,浏览器会有对应的下载进程来下载文件,而移动端应用则是直接将下载文件写入到内存或本地文件中,下载文件还是可以使用第三方库rn-fetch-blob

以下只是简单的示例,详细示例可以查看文档,还有配置查看下载进程、配置Android调用系统下载管理器

RNFetchBlob
  .config({
    // downPath为指定路径,fileName为指定的文件名
    path: downPath + \'/\' + fileName,
  }).fetch(\'GET\', url).then((res) => {
    console.log(\'下载完成文件保存路径为\\n\' + res.path())
  }).catch((err)=>console.log(\'err\',err))
收藏 打印