Как преобразовать объект javascript в фактический файл, чтобы загрузить с помощью HTML5

У меня есть объект javascript с огромным количеством данных в нем, включая несколько больших закодированных строк base64.

В настоящее время мы отправляем данные на сервер с помощью простого ajax POST, но поскольку данные настолько велики, время ожидания для пользователя неприемлемо.

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

Чтобы использовать эту функцию, этот большой массив должен быть отправлен как фактический файл, а не как огромный объект, отправленный как параметры URL.

Есть ли какой-либо способ:

а. Преобразуйте этот объект в фактический текстовый файл и отправьте его таким образом.

или

В. Подключитесь в html5 progress api и на самом деле измеряйте ход этого стандартного ajax POST.

Спасибо заранее.

Ответ 1

Можно взять объект JavaScript (myData), подстроить его в JSON, упаковать в Blob mimetype JSON и отправить его на сервер с API загрузки HTML5. Вы можете использовать прогресс (в функции обратного вызова progress), чтобы обновить значение индикатора выполнения HTML5.

var myData = {
    data1: "Huge amount of data",
    data2: "More very large data"
};

var xhr = new XMLHttpRequest();

xhr.upload.addEventListener('progress', function (e) {
    console.log(100*(e.loaded / e.total) + '%');
}, false);

xhr.open('POST', 'url', true);

var data = new FormData();
data.append('file', new Blob([JSON.stringify(myData)],{type:'application/json'}));
xhr.send(data);

Ответ 2

Преобразуйте объект Blob или объект File, затем добавьте к FormData и используйте xhr или fetch для отправки на сервер.

var data = 'some data'; //string, arrary buffer, typed array, blob, ...
var filename01 = 'abc.txt', filename02 = 'efg.txt';
var type = 'text/plain';
var fd = new FormData();

//use file object
var file = new File([data], filename01, {type:type}); //add filename here
fd.append('file01', file);

//use blob object
var blob = new Blog([data], {type:type});
fd.append('file02', blob, filename02); //add filename by append method

fetch('/server.php', {method:'POST', body:fd})
.then(function(res){
    return res.text();
})
.then(console.log)
.catch(console.error)
;