react-native之檔案上傳下載
目錄
最近react-native專案上需要做檔案上傳下載的功能,由於才接觸react-native不久,好多東西不熟悉,前期花了不少時間去探索,在此記錄下探索後的成果
檔案上傳
1.檔案選擇
檔案上傳前需要選擇相應的檔案,可以使用第三方庫react-native-file-selector來選擇檔案,以下是安卓和IOS上的互動效果
引入react-native-file-selector,該庫的詳細使用方式檢視
npm i -S react-native-file-selector
react-native link react-native-file-selector
注意:
- react-native-file-selector在link後在android上可能會有些問題,需要手動link,可以看官方的android手動link
如果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)
包裝好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))