zoukankan      html  css  js  c++  java
  • react-native之文件上传下载


    最近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 link react-native-file-selector

    注意:

    1. react-native-file-selector在link后在android上可能会有些问题,需要手动link,可以看官方的android手动link

    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(
        {
            title: '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 xmlHttp = new XMLHttpRequest()
    xmlHttp.open('post', url)
    xmlHttp.onerror = (err) => { 'error', err }
    xmlHttp.onreadystatechange = () => {
      if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        console.log('res', xmlHttp.response)
      }
    }
    xmlHttp.setRequestHeader('Content-Type', 'multipart/form-data')
    xmlHttp.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('下载完成文件保存路径为
    ' + res.path())
      }).catch((err)=>console.log('err',err))
    
  • 相关阅读:
    心得
    第七章
    第六章
    第五章
    第四章
    第三章
    第二章
    第一章
    实验2(4)
    实验2(3)
  • 原文地址:https://www.cnblogs.com/eyelly/p/react-native-file-upload-download.html
Copyright © 2011-2022 走看看