Skip to content

Instantly share code, notes, and snippets.

@jfoclpf
Last active January 9, 2021 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfoclpf/07e52f6bdf9c967449c4bc06af44c94a to your computer and use it in GitHub Desktop.
Save jfoclpf/07e52f6bdf9c967449c4bc06af44c94a to your computer and use it in GitHub Desktop.
Pure Vanilla Javascript download and upload functions for Apache Cordova

Pure Vanilla Javascript download and upload functions for Apache Cordova

The cordova plugin cordova-plugin-file-transfer is due to be deprecated and its latest npm version fails on iOS.

Therefore these two working functions are purely based on JS, and thus no need to use extra plugins, besides the standard plugin cordova-plugin-file. Therefore this is compatible with any platform.

// for different types of cordovaFileSystem check here: 
// https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/#where-to-store-files
// or simply type in the console `console.log(cordova.file)`
function downloadFileToDevice (fileurl, filename, cordovaFileSystem, callback) {
  var onerror = (err) => {
    console.error(`Error downloading from ${fileurl} to cordovaFileSystem ${cordovaFileSystem}`, 
    err, new Error(err))
    if (typeof callback === 'function') { callback(Error(err)) }
  }

  var blob = null
  var xhr = new XMLHttpRequest()
  xhr.open('GET', fileurl)
  xhr.responseType = 'blob' // force the HTTP response, response-type header to be blob
  xhr.onload = () => {
    blob = xhr.response // xhr.response is now a blob object
    var DataBlob = blob
    window.resolveLocalFileSystemURL(cordovaFileSystem, (dirEntry) => {
      const sanitizedFilename = filename.replace(/[^a-z0-9\.]/gi, '_').toLowerCase() // sanitize filename
      dirEntry.getFile(sanitizedFilename, { create: true }, (file) => {
        file.createWriter((fileWriter) => {
          fileWriter.write(DataBlob)
          if (typeof callback === 'function') { callback(null, cordovaFileSystem + sanitizedFilename) }
        }, (err) => { console.error('Error on file.createWriter'); onerror(err) })
      }, (err) => { console.error('Error on dirEntry.getFile'); onerror(err) })
    }, (err) => { console.error('Error on resolveLocalFileSystemURL'); onerror(err) })
  }
  xhr.onerror = (err) => { console.error('Error on XMLHttpRequest'); onerror(err) }
  xhr.send()
}
function uploadFileToServer (fileUri, fileName, remoteUrl, callback) {
  var onerror = (err) => {
    console.error(`Error uploading file ${fileUri} to ${remoteUrl}`,
      err, new Error(err))
    if (typeof callback === 'function') { callback(Error(err)) }
  }

  window.resolveLocalFileSystemURL(fileUri, function (fileEntry) {
    fileEntry.file((file) => {
      if (!file.size) { onerror('File is empty (on fileEntry from resolveLocalFileSystemURL)'); return }
      var reader = new FileReader()
      reader.onloadend = () => {
        var blob = new Blob([new Uint8Array(reader.result)], { type: 'application/octet-stream' })
        if (!blob.size) { onerror('File is empty (on blob)'); return }
        var fd = new FormData()
        fd.append('file', blob, fileName)

        var xhr = new XMLHttpRequest()
        xhr.open('POST', remoteUrl, true)
        xhr.onload = function () {
          if (xhr.status === 200 || xhr.status === 201) {
            if (typeof callback === 'function') { callback() }
          } else {
            console.error('Error on xhr.status: ' + xhr.status); onerror(xhr.status)
          }
        }
        xhr.onerror = (err) => { console.error('Error on XMLHttpRequest'); onerror(err) }
        xhr.send(fd)
      }
      reader.onerror = (err) => { console.error('Error on FileReader'); onerror(err) }
      reader.readAsArrayBuffer(file)
    }, (err) => { console.error('Error on fileEntry.file'); onerror(err) })
  }, (err) => { console.error('Error on resolveLocalFileSystemURL'); onerror(err) })
}

An example for download

downloadFileToDevice('https://example.com/img.jpg',
  'myImg.jpg', 
  cordova.file.cacheDirectory,
  (err, localFilePath) => {
    if (err) {
      console.error('An error occured downloading file:', err)
    } else {
      console.log('Download file with success: ' + localFilePath)
    }
})

An example for upload, exactly as the ft.upload in cordova-plugin-file-transfer

uploadFileToServer('file:///storage/emulated/0/Android/data/myfile.jpg',
  'myfileNameOnServer.jpg',
  'https://example.com/upload_url',
  (err) => {
    if (err) {
      console.error('Error uploading file:', err)
    } else {
      console.log('Upload done it with success')
    }
  })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment