如何使用app原生上傳替代uniapp的uploadfile介面
uniapp簡介
uniapp是近兩年來比較火的號稱開發者編寫一套程式碼,可釋出到iOS、Android、Web(響應式)、以及各種小程式的一個平臺,它提供了各種豐富的API文件讓開發者快速的完成各種功能。
但是由於uniapp是一個新興平臺,生態還不夠完整,難免會出現一些bug。今天我們就來講講uniapp官方上傳檔案API的坑以及如何使用原生app寫法代替uniapp的上傳介面。
uniapp官方上傳檔案介面uni.uploadFile(OBJECT)
將本地資源上傳到開發者伺服器,客戶端發起一個 POST 請求,其中 content-type 為 multipart/form-data。
介面引數:
如果你只需要上傳檔案而不需要監控實時上傳進度,則使用uni.uploadFile介面即可。
為何需要使用app原生上傳代替 uniapp官網的uploadFile介面
原因有兩點:
1、如果希望監控上傳進度,則需要返回一個 uploadTask 物件,用這個物件的 onProgressUpdate方法進行監聽上傳進度,使用abort方法取消上傳任務。而這個uploadTask物件如果定義為頁面全域性物件則onProgressUpdate方法和abort方法有時候會不執行,導致無法監聽上傳進度和取消任務。
2、onProgressUpdate監聽的上傳進度與實際進度不相符。僅表現在安卓端,IOS端無這種情況。具體原因是我上傳一個30多M的檔案,剛開始進度是0,突然一下子嗖的就變成了100,導致頁面的進度條也是一下子從0變到100,然後就在100 這裡卡住。其實是遠沒有上傳完的。等了好幾秒才顯示完成。
如何使用app原生上傳檔案
對原生介面文件感興趣的小夥伴可以從這裡進去。下面我直接貼上我的程式碼並通過註釋進行程式碼講解。
// 傳送檔案方法 sendFile(e) { //filePath是檔案的本地路徑,呼叫plus.io.convertAbsoluteFileSystem方法可以將平臺絕對路徑轉換成本地URL路徑 const filePath = plus.io.convertAbsoluteFileSystem(e.filePath) // 這是後端伺服器的檔案上傳地址 const url = this.$urlConfig.mattermost + '/plugins/plugin_ruixin_base/file/post' // 這是建立上傳任務時所需要到的配置引數 const uploadOptions = { // 分塊上傳的大小單位kb,Android平臺需設定分塊上傳才能準確觸發statechanged返回上傳進度,ios自動忽略 chunkSize: 100, method: 'POST' } // 建立上傳任務 this.uploadTask = plus.uploader.createUpload(url,uploadOptions) // 往上傳任務裡新增檔案,第二個引數的欄位有預設值,可以傳空物件{}即可,但是不能不傳 this.uploadTask.addFile(filePath, {}) // 這裡可以將新增檔案的返回值打印出來,true表示新增檔案成功,false表示新增失敗 // console.log('新增檔案', this.uploadTask.addFile(filePath, {})) // 往接口裡新增其他額外的請求引數,第一個引數是key,第二個引數是value this.uploadTask.addData('string_key1', 'string_value1') // 這裡可以將新增額外請求引數的返回值打印出來,true表示新增成功,false表示新增失敗 // console.log('新增額外請求引數', this.uploadTask.addData('string_key1', 'string_value1')) this.uploadTask.addData('string_key2', 'string_value2') // 設定請求頭資訊,根據後端介面的要求設定 this.uploadTask.setRequestHeader('headerName1', 'headerValue1') this.uploadTask.setRequestHeader('headerName2', 'headerValue2') // 注意:上面addFile、addData中但凡有一個返回false,都不能上傳成功。請檢查是否設定錯了 // 新增事件監聽器用於監聽實時進度和完成情況,第一個引數為“statechanged”,第二個引數是回撥方法 this.uploadTask.addEventListener( "statechanged", (upload, status) =>{ switch (upload.state) { case 1: // 上傳任務開始請求 break case 2: // 上傳任務請求已經建立 break case 3: // 上傳任務提交資料,監聽 statechanged 事件時可多次觸發此狀態。(重點) // uploadedSize表示當前已經上傳了的資料大小,totalSize表示檔案總大小,單位是位元組b console.log('上傳進度',parseInt(100 * upload.uploadedSize/upload.totalSize) ) break case 4: // 上傳任務已完成, 無論成功或失敗都會執行到 4 這裡 if (status === 200) { // 上傳成功 } else { // 上傳失敗 } } }) // 開始執行上傳任務 this.uploadTask.start() }
執行程式碼之後打印出比較精確的實時上傳進度
總結
uniapp上傳檔案的介面uploadfile主要的坑在於如果你想監控實時上傳進度,在安卓端它無法提供一個實時準確的上傳進度。如果不需要監控實時上傳進度,使用uploadfile介面還是很不錯的,使用簡單便捷。原生上傳檔案介面雖然比較複雜,但是好在安卓和蘋果都能支援,保證了相容性。