Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save isocroft/9a12605b23713af4dd3eef4e6e9de565 to your computer and use it in GitHub Desktop.

Select an option

Save isocroft/9a12605b23713af4dd3eef4e6e9de565 to your computer and use it in GitHub Desktop.
How to upload 50 GB of file data using client-side JavaScript
const fileInput = window.document.getElementById('file_input');
const fileUploadChunkSize = 10 * Math.pow(1024, 2) // 10 by 1MB = 10MB
fileInput.adddEvenListener('change', (event) => {
const [ file ] = event.target.files;
const reader = file.stream().getReader();
let uploadedBytes = 0;
console.info('Upload Start >');
reader.read().then(function process ({ done, value }) {
if (done) {
return console.info('Upload Complete!');
}
window.fetch("/upload", {
method: "POST",
headers: {
'Content-Range': `bytes ${uploadedBytes}-${uploadedBytes + value.length}/${file.size}`
},
body: value
}).then(() => {
uploadedBytes += value.length;
console.info(`Upload Progress: ${(uploadedBytes / file.size * 100).toFixed(2)}%`);
return reader.read().then(process);
}).catch(() => console.info('Retrying...') && reader.read().then(process));
});
});
@isocroft

Copy link
Copy Markdown
Author
//our extend function
function extendConstructorWithDispatch (constructor, parent) {
    var constructorName = constructor.name

    //which returns a constructor
    parent[constructorName] = function (urlOrPath) {

      var event = new w.CustomEvent('beforerequest', {
        detail: {
          endpoint: urlOrPath.toString().indexOf('http') == 0 ? w.location.origin + "/" + urlOrPath : urlOrPath.toString(),
          method:"GET"
        },
        bubbles: false,
        cancelable: true
      });

      var cancelled = !d.dispatchEvent(event);
            
      if(cancelled){
        throw new Error("Suspicious Activity: " + event.detail.endpoint + " request, as ["+ event.detail.method+"]");
      }
        
      //that calls the parent constructor with itself as scope
      return constructor.apply(this, arguments.slice(0));
    }

    //make the prototype an instance of the old class
    parent[constructorName].prototype = Object.create(constructor.prototype);
    
    return parent[constructorName];
};

extendConstructorWithDispatch(window.EventSource, window);
// NODEJS
const FileType = require('file-type'); /* https://www.npmjs.com/package/file-type/v/16.5.4 */
const chunks = new Buffer(0);
const stream = new ReadableStream();

stream.on('data', function(datum){
 chunks.push(datum);
});
stream.on('end', function(){
 const contentType = extractMimeType(chunks, FileType);
 const contentLength = isUTFBytes(chunks) ? Buffer.byteLength(chunks) : chunks.reduce(function(lengthSum, chunk){
  return lengthSum + chunk.length;
 }, 0);
 const fileBuffered = Buffer.concat(chunks);
 const header = "data:${contentType};base64, ";
 const body = `${fileBuffered.toString("base64")}`;

 const stringContentLength = header.length + body.length;
 const stringContentType = "text/plain";
 const stringContent = header + body;
});


// BROWSER

const base64 = 'data:image/png;base64,....' // Place your base64 url here.

const fd = fetch(base64)
.then(res => res.blob())
.then(blob => {
  const formData = new FormData();
  const file = new File([blob], "filename.jpeg");

  formData.append('image', file);
  return formData;
});
  
 // Let's upload the file
 // Don't set contentType manually → https://github.com/github/fetch/issues/505#issuecomment-293064470

const API_URL = 'https://example.com/add_image';
 
fetch(API_URL, {method: 'POST', body: fd)
 .then(res => res.json()) 
 .then(res => console.log(res))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment