斷點上傳實踐

第一次發文,文筆很爛,技術很渣,大佬們不喜勿噴。55555

背景

一次去面試,給自己挖了一個坑,被問到有沒有做到斷點上傳,知不知道其中的原理,瞬間進入懵逼狀態。下來后去網上查了一些資料,寫了一個簡單的demo。

原理

斷點上傳,顧名思義,一個文件可以分多次上傳。核心點就是前端將文件分塊傳給后端,后端再進行拼接,最后完整文件上傳。

html5提供了FileApi, 可以用file.slice將文件分塊,不支持html5的可以用flash實現

代碼

前端代碼

function upload(file) {
  var cache = 0
  var thunk = 1024
  var totalSize = file.size
    
  send()
    
  function send() {
    var form = new FormData()
    form.append('file', file.slice(cache, cache + thunk))
    form.append('fileName', file.name)
    ajax(form, function(response) {
      cache = cache + thunk
      document.getElementById('uploadProgress').innerText = (cache / totalSize > 1 ? 1 : cache / totalSize) * 100 + '%'
      if (cache < totalSize) {
        send()
      }
    })
  }
}
    
function ajax(data, cb) {
  var xhr = new XMLHttpRequest()
  xhr.open('post', '/upload')
  xhr.send(data)
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        cb && cb(xhr.reponse)
      }
    }
  }
}

后端代碼

const file = ctx.request.body.files.file
const fileName = ctx.request.body.fields.fileName
const reader = fs.createReadStream(file.path)
reader.on('data', function(chunk) {
  // 暫停讀取
  reader.pause()
  fs.appendFile(path.join(__dirname, 'upload', fileName), chunk, function(err) {
    if (err) {
      ctx.body = 'error'
    }
    // 繼續讀取
    reader.resume()
  })
})

reader.end(function() {
    ctx.body = 'completed'
})

總結

當然功能還存在很多缺陷,比如怎么實現多個塊同時上傳,手動暫停,保存已上傳的狀態等等,后面再慢慢完善。

By 走刀口(Chris Wong)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容