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,問題原因(需翻牆)

    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('下載完成文件保存路徑為\n' + res.path())
  }).catch((err)=>console.log('err',err))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM