В некоторых ситуациях может возникнуть загрузка большого файла через javascript вместо публикации HTML-формы, куда мы можем отправить его как составные данные. Обычно ситуация возникает, когда разработчики делают вызовы REST API из Javascript.

Загрузить небольшие файлы очень просто, прочитав файл как base64 и отправив его на сервер.

Простая загрузка файла:

Это очень просто, FileReader в HTML5 помогает читать файл и конвертирует в base64. Ниже код для загрузки небольших файлов (до 2 МБ)

function uploadFile() {
 // Check for the various File API support.
 if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
  alert('The File APIs are not fully supported in this browser.');
 }

 var fileContent;
 var reader = new FileReader();
 reader.onload = function() {
  binaryFileData = reader.result;
  var bytes = new Uint8Array(reader.result), binary = "";
  var length = bytes.byteLength;
  for (var i = 0; i < length; i++) {
   binary += String.fromCharCode(bytes[i]);
  }
  fileContent = btoa(binary);
  var data = {
   file : fileContent
  };

  $.post("https://api.jquery.com/jquery.post/", function(data) {
  });
     };
     reader.readAsArrayBuffer(document.getElementById("FileUploadControl").files[0]);
 }

Приведенный выше сценарий не будет работать с большими файлами. Файл должен быть прочитан по частям, и для этого мы должны использовать рабочие потоки, как показано ниже:

Рабочий поток должен быть отдельным файлом JS.

function parseFile(file, callback) {
var fileSize = file.size;
var chunkSize = 512 * 1024; // bytes
var offset = 0;
var block = null;
var r = null;

var foo = function(evt) {
 var binary = "";
 if (evt.target.error == null) {
  // console.log(evt, evt.target.result.length);
  offset += evt.loaded;
  r = new Uint8Array(evt.target.result);
  for (var i = 0, l = r.length; i < l; i++) {
   binary += String.fromCharCode(r[i]);
  }
  callback([ false, offset, binary ]); // callback for handling read chunk
 } else {
  console.log("Read error: " + evt.target.error);
  callback([ true, '', '' ]);
  return;
 }
 if (offset >= fileSize) {
  // console.log("CRC32: " + );
  callback([ true, '', '' ]);
  return;
 }

  block(offset, chunkSize, file);
 };

 block = function(_offset, length, _file) {
  var r = new FileReader();
  var blob = _file.slice(_offset, length + _offset);
  r.onload = foo;
  r.readAsArrayBuffer(blob);
 };

 block(offset, chunkSize, file);
}

onmessage = function(e) {
 parseFile(e.data, function(evt) {
  postMessage([ evt[0], evt[1], evt[2] ]);
 });
};

Основная тема:

var fileUploadWorker = new Worker("fileReaderWorker.js");
var base64 = '';
fileUploadWorker.postMessage(file);
fileUploadWorker.onmessage = function(z) {
 if (z.data[0]) {
  var fileContent=btoa(base64);// File Read Completes
  //invoke API
 } else {
  base64 += z.data[2];
  var val = (z.data[1] / file.size);
  console.log("Read Completed:" + (val * 100).toFixed(2) + '%');
 }
};

Здесь файл конвертируется в base64 и отправляется в запросе POST. Обратите внимание, что размер строки base64 на 33% больше, чем фактический размер файла.

Просмотреть все сообщения selvakumarponnusamy