diff --git a/site/templates/upload.html b/site/templates/upload.html index dbeb860..0f1f910 100644 --- a/site/templates/upload.html +++ b/site/templates/upload.html @@ -60,7 +60,7 @@
Nubes - Сверка договоров v2.0.3 + Сверка договоров v2.0.4
@@ -172,51 +172,44 @@ } var b64 = btoa(b64Chunks.join('')); var checksum = SparkMD5.ArrayBuffer.hash(buffer); - var CHUNK = 30 * 1024; + var CHUNK = 55 * 1024; // меньше запросов → меньше HTTP/2 ошибок var totalChunks = Math.ceil(b64.length / CHUNK); var uploadId = 'u' + Date.now().toString(36) + Math.random().toString(36).substr(2, 7); var done = 0; console.log('uploadFileChunked: ' + file.name + ' b64=' + b64.length + ' chunks=' + totalChunks + ' uploadId=' + uploadId); + function sendChunk(i) { if (i >= totalChunks) { console.log('finalize: ' + uploadId); - var xhr = new XMLHttpRequest(); - xhr.open('POST', '/v2/finalize'); - xhr.setRequestHeader('Content-Type', 'application/json'); - xhr.timeout = 60000; - xhr.onload = function() { - try { - var r = JSON.parse(xhr.responseText); - if (r.ok) resolve({contract_id: r.contract_id}); - else reject(new Error(r.error)); - } catch(e) { reject(new Error('Bad JSON')); } - }; - xhr.onerror = function() { reject(new Error('Сеть')); }; - xhr.ontimeout = function() { reject(new Error('Таймаут')); }; - xhr.send(JSON.stringify({upload_id: uploadId, filename: file.name, total: totalChunks, checksum: checksum})); + fetch('/v2/finalize', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({upload_id: uploadId, filename: file.name, total: totalChunks, checksum: checksum}) + }).then(function(r) { + if (!r.ok) throw new Error('HTTP ' + r.status); + return r.json(); + }).then(function(data) { + if (data.ok) resolve({contract_id: data.contract_id}); + else reject(new Error(data.error)); + }).catch(function(e) { reject(e); }); return; } var piece = b64.substring(i * CHUNK, (i + 1) * CHUNK); console.log('chunk ' + i + '/' + totalChunks + ' send ' + piece.length + ' bytes'); - var xhr = new XMLHttpRequest(); - xhr.open('POST', '/v2/chunk'); - xhr.setRequestHeader('Content-Type', 'application/json'); - xhr.timeout = 30000; - xhr.onload = function() { - if (xhr.status === 200) { - try { - var r = JSON.parse(xhr.responseText); - if (!r.ok) { reject(new Error(r.error)); return; } - done++; - if (onProgress) onProgress(Math.round(done / totalChunks * 100)); - setTimeout(function() { sendChunk(i + 1); }, 50); - } catch(e) { reject(new Error('Bad JSON')); } - } else { reject(new Error('HTTP ' + xhr.status)); } - }; - xhr.onerror = function() { reject(new Error('Сеть')); }; - xhr.ontimeout = function() { reject(new Error('Таймаут')); }; - xhr.send(JSON.stringify({upload_id: uploadId, index: i, total: totalChunks, data: piece})); + fetch('/v2/chunk', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({upload_id: uploadId, index: i, total: totalChunks, data: piece}) + }).then(function(r) { + if (!r.ok) throw new Error('HTTP ' + r.status); + return r.json(); + }).then(function(data) { + if (!data.ok) { reject(new Error(data.error)); return; } + done++; + if (onProgress) onProgress(Math.round(done / totalChunks * 100)); + setTimeout(function() { sendChunk(i + 1); }, 500); // дать HTTP/2 стримам закрыться + }).catch(function(e) { reject(e); }); } sendChunk(0); };