В некоторых ситуациях может возникнуть загрузка большого файла через 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