1. 程式人生 > 實用技巧 >如何使用app原生上傳替代uniapp的uploadfile介面

如何使用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介面還是很不錯的,使用簡單便捷。原生上傳檔案介面雖然比較複雜,但是好在安卓和蘋果都能支援,保證了相容性。