uniapp uni.downloadFile 偶发性下载文件失败 无响应

背景

uniapp开发的安卓app运行时,uni.downloadFile下载文件,偶发性下载失败、没有反应,也不进入complete回调函数,onProgressUpdate也不执行,代码如下

复制代码
var uploadTask = uni.downloadFile({
    url:"",
    success:function(res){
      //输出res.tempFilePath之类的
    },
    fail:function(e){

    },
    complete:function(e){
        //不进入
    }
})

//进度更新
uploadTask.onProgressUpdate((result) => {
    //也不进入
})

同事使用plus api可以成功下载

复制代码
plus.downloader.createDownload(
      url,
      {
        timeout,
        filename: TEMP_PATH + '/download/',
        // 需要与其它平台上的表现保持一致,不走重试的逻辑。
        retry: 0,
        retryInterval: 0,
      },

解决

百度相关帖子,发现有的下载失败是因为url中有特殊字符,而我不属于这种情况,好在这个bug能稳定复现,经观察,

失败时服务器端写入的http Response Header如下

复制代码
Content-Disposition: inline; filename="Some's file name.pdf";

抱着试一试的心态,将filename中特殊字符单引号('),去掉后,成功下载。

后续

带着好奇心,看了下uniapp的源码,

h5版本的源码

复制代码
xhr.onload = function () {
      clearTimeout(timer)
      const statusCode = xhr.status
      const blob = this.response
      let filename
      // 使用 getResponseHeader 跨域时会出现警告,但相比 getAllResponseHeaders 更方便
      const contentDisposition = xhr.getResponseHeader('content-disposition')
      if (contentDisposition) {
        // 暂时仅解析 filename 不解析 filename*
        const res = contentDisposition.match(/filename="?(\S+)"?\b/)
        if (res) {
          filename = res[1]
        }
      }
      blob.name = filename || getFileName(url)
      resolve({
        statusCode,
        tempFilePath: fileToUrl(blob),
      })
}
xhr.onabort = function () {
    clearTimeout(timer)
    reject<Partial<DownloadFileFail>>('abort', { errCode: 600003 })
}
xhr.onerror = function () {
  clearTimeout(timer)
  reject<Partial<DownloadFileFail>>('', { errCode: 602001 })
}

app版本的源码

复制代码
const downloader = plus.downloader.createDownload(
      url,
      {
        timeout,
        filename: TEMP_PATH + '/download/',
        // 需要与其它平台上的表现保持一致,不走重试的逻辑。
        retry: 0,
        retryInterval: 0,
      },
      (download, statusCode) => {
        if (statusCode) {
          resolve({
            tempFilePath: download.filename!,
            statusCode,
          })
        } else {
          reject(`statusCode: ${statusCode}`)
        }
      }
    )

推测

安卓运行,会执行app版本源码?如果是,从app版源码上,看不出来有什么问题,只能推测是上一层uni封装downloadFile时,解析fileName出问题了。

相关推荐
小徐_23332 小时前
uni-app 项目别再从零搭了!3 个 Wot UI 起手模板怎么选?
前端·uni-app
蜡台2 小时前
uniapp pdf文件预览组件
pdf·uni-app·合同·pdfh5
凡泰AI7 小时前
如何借助MCP打通企业APP内部服务:从统一调用到小程序承接
小程序·uni-app·app·mpaas·mcp·小程序容器
华玥作者9 小时前
uniapp 万条数据不卡顿:我写了个虚拟列表组件 hy-list,原生支持瀑布流
数据结构·uni-app·list·vue3
这是个栗子9 小时前
uni-app 微信小程序开发:常用函数总结(一)
微信小程序·小程序·uni-app·getcurrentpages
宠友信息2 天前
消息序号如何保证即时通讯源码聊天记录稳定加载
java·spring boot·redis·python·mysql·uni-app
2501_916008892 天前
苹果上架工具怎么选 不用 Mac 上架 App Store 的几种方案
android·macos·ios·小程序·uni-app·iphone·webview
宠友信息2 天前
MySQL复合索引与Druid优化仿小红书源码个人主页查询链路
数据库·spring boot·websocket·mysql·uni-app
秃头披风侠_郑3 天前
【uniapp】一文让你学会微信小程序+APP+H5全平台实战指南
前端·微信小程序·uni-app
宠友信息4 天前
消息撤回与已读状态如何在即时通讯源码中统一管理
java·spring boot·websocket·mysql·uni-app