Resumable upload by wingedfox · Pull Request #57 · mailru/FileAPI
Expand Up
@@ -65,7 +65,7 @@
// Start uploading
options.upload(options, _this);
_this._send.call(_this, options, data);
});
}, options);
},
_send: function (options, data){ Expand All @@ -77,6 +77,7 @@ url += (~url.indexOf('?') ? '&' : '?') + api.uid();
if( data.nodeName ){ // legacy options.upload(options, _this);
xhr = document.createElement('div'); Expand Down Expand Up @@ -125,6 +126,7 @@ form = null; } else { // html5 xhr = _this.xhr = api.getXHR();
xhr.open('POST', url, true); Expand All @@ -138,46 +140,114 @@ xhr.setRequestHeader(key, val); });
if( xhr.upload ){ // https://github.com/blueimp/jQuery-File-Upload/wiki/Fixing-Safari-hanging-on-very-high-speed-connections-%281Gbps%29 xhr.upload.addEventListener('progress', api.throttle(function (/**Event*/evt){ options.progress(evt, _this, options); }, 100), false); }
xhr.onreadystatechange = function (){ _this.status = xhr.status; _this.statusText = xhr.statusText; _this.readyState = xhr.readyState;
if (api.support.chunked && options.chunkSize > 0) { // resumable upload if( xhr.upload ){ // https://github.com/blueimp/jQuery-File-Upload/wiki/Fixing-Safari-hanging-on-very-high-speed-connections-%281Gbps%29 xhr.upload.addEventListener('progress', api.throttle(function (/**Event*/evt){ var e = api.extend({}, evt, { loaded : data.start + evt.loaded, totalSize : data.size, total : data.size}); options.progress(e, _this, options); }, 100), false); }
if( xhr.readyState == 4 ){ for( var k in { '': 1, XML: 1, Text: 1, Body: 1 } ){ _this['response'+k] = xhr['response'+k]; xhr.onreadystatechange = function (){ _this.status = xhr.status; _this.statusText = xhr.statusText; _this.readyState = xhr.readyState;
if( xhr.readyState == 4 ){ for( var k in { '': 1, XML: 1, Text: 1, Body: 1 } ){ _this['response'+k] = xhr['response'+k]; } xhr.onreadystatechange = null;
if (xhr.status - 201 > 0) { // some kind of error if (++data.retry <= options.chunkUploadRetry && (500 == xhr.status || 416 == xhr.status)) { // let's try again the same chunk // only applicable for recoverable error codes 500 && 416 data.end = data.start _this._send(options, data); } else { // no mo retries _this.end(xhr.status); } } else { // success data.retry = 0;
if (data.end == data.size - 1) { // finished _this.end(xhr.status); } else { // next chunk _this._send(options, data); } } xhr = null; } xhr.onreadystatechange = null; _this.end(xhr.status); xhr = null; };
data.start = data.end; data.end = Math.min(data.end + options.chunkSize, data.size ) - 1;
var slice; (slice = 'slice') in data.file || (slice = 'mozSlice') in data.file || (slice = 'webkitSlice') in data.file;
xhr.setRequestHeader("Content-Range", "bytes " + data.start + "-" + data.end + "/" + data.size); xhr.setRequestHeader("Content-Disposition", 'attachment; filename=' + data.name);
slice = data.file[slice](data.start, data.end + 1);
xhr.send(slice); slice = null; } else { // single piece upload if( xhr.upload ){ // https://github.com/blueimp/jQuery-File-Upload/wiki/Fixing-Safari-hanging-on-very-high-speed-connections-%281Gbps%29 xhr.upload.addEventListener('progress', api.throttle(function (/**Event*/evt){ options.progress(evt, _this, options); }, 100), false); } };
xhr.onreadystatechange = function (){ _this.status = xhr.status; _this.statusText = xhr.statusText; _this.readyState = xhr.readyState;
if( xhr.readyState == 4 ){ for( var k in { '': 1, XML: 1, Text: 1, Body: 1 } ){ _this['response'+k] = xhr['response'+k]; } xhr.onreadystatechange = null; _this.end(xhr.status); xhr = null; } };
if( api.isArray(data) ){ // multipart xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=_'+api.expando); data = data.join('') +'--_'+ api.expando +'--'; if( api.isArray(data) ){ // multipart xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=_'+api.expando); data = data.join('') +'--_'+ api.expando +'--';
/** @namespace xhr.sendAsBinary https://developer.mozilla.org/ru/XMLHttpRequest#Sending_binary_content */ if( xhr.sendAsBinary ){ xhr.sendAsBinary(data); } else { var bytes = Array.prototype.map.call(data, function(c){ return c.charCodeAt(0) & 0xff; }); xhr.send(new Uint8Array(bytes).buffer); /** @namespace xhr.sendAsBinary https://developer.mozilla.org/ru/XMLHttpRequest#Sending_binary_content */ if( xhr.sendAsBinary ){ xhr.sendAsBinary(data); } else { var bytes = Array.prototype.map.call(data, function(c){ return c.charCodeAt(0) & 0xff; }); xhr.send(new Uint8Array(bytes).buffer);
} } else { // FormData xhr.send(data); } } else { xhr.send(data); } } } }; Expand Down
_send: function (options, data){ Expand All @@ -77,6 +77,7 @@ url += (~url.indexOf('?') ? '&' : '?') + api.uid();
if( data.nodeName ){ // legacy options.upload(options, _this);
xhr = document.createElement('div'); Expand Down Expand Up @@ -125,6 +126,7 @@ form = null; } else { // html5 xhr = _this.xhr = api.getXHR();
xhr.open('POST', url, true); Expand All @@ -138,46 +140,114 @@ xhr.setRequestHeader(key, val); });
if( xhr.upload ){ // https://github.com/blueimp/jQuery-File-Upload/wiki/Fixing-Safari-hanging-on-very-high-speed-connections-%281Gbps%29 xhr.upload.addEventListener('progress', api.throttle(function (/**Event*/evt){ options.progress(evt, _this, options); }, 100), false); }
xhr.onreadystatechange = function (){ _this.status = xhr.status; _this.statusText = xhr.statusText; _this.readyState = xhr.readyState;
if (api.support.chunked && options.chunkSize > 0) { // resumable upload if( xhr.upload ){ // https://github.com/blueimp/jQuery-File-Upload/wiki/Fixing-Safari-hanging-on-very-high-speed-connections-%281Gbps%29 xhr.upload.addEventListener('progress', api.throttle(function (/**Event*/evt){ var e = api.extend({}, evt, { loaded : data.start + evt.loaded, totalSize : data.size, total : data.size}); options.progress(e, _this, options); }, 100), false); }
if( xhr.readyState == 4 ){ for( var k in { '': 1, XML: 1, Text: 1, Body: 1 } ){ _this['response'+k] = xhr['response'+k]; xhr.onreadystatechange = function (){ _this.status = xhr.status; _this.statusText = xhr.statusText; _this.readyState = xhr.readyState;
if( xhr.readyState == 4 ){ for( var k in { '': 1, XML: 1, Text: 1, Body: 1 } ){ _this['response'+k] = xhr['response'+k]; } xhr.onreadystatechange = null;
if (xhr.status - 201 > 0) { // some kind of error if (++data.retry <= options.chunkUploadRetry && (500 == xhr.status || 416 == xhr.status)) { // let's try again the same chunk // only applicable for recoverable error codes 500 && 416 data.end = data.start _this._send(options, data); } else { // no mo retries _this.end(xhr.status); } } else { // success data.retry = 0;
if (data.end == data.size - 1) { // finished _this.end(xhr.status); } else { // next chunk _this._send(options, data); } } xhr = null; } xhr.onreadystatechange = null; _this.end(xhr.status); xhr = null; };
data.start = data.end; data.end = Math.min(data.end + options.chunkSize, data.size ) - 1;
var slice; (slice = 'slice') in data.file || (slice = 'mozSlice') in data.file || (slice = 'webkitSlice') in data.file;
xhr.setRequestHeader("Content-Range", "bytes " + data.start + "-" + data.end + "/" + data.size); xhr.setRequestHeader("Content-Disposition", 'attachment; filename=' + data.name);
slice = data.file[slice](data.start, data.end + 1);
xhr.send(slice); slice = null; } else { // single piece upload if( xhr.upload ){ // https://github.com/blueimp/jQuery-File-Upload/wiki/Fixing-Safari-hanging-on-very-high-speed-connections-%281Gbps%29 xhr.upload.addEventListener('progress', api.throttle(function (/**Event*/evt){ options.progress(evt, _this, options); }, 100), false); } };
xhr.onreadystatechange = function (){ _this.status = xhr.status; _this.statusText = xhr.statusText; _this.readyState = xhr.readyState;
if( xhr.readyState == 4 ){ for( var k in { '': 1, XML: 1, Text: 1, Body: 1 } ){ _this['response'+k] = xhr['response'+k]; } xhr.onreadystatechange = null; _this.end(xhr.status); xhr = null; } };
if( api.isArray(data) ){ // multipart xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=_'+api.expando); data = data.join('') +'--_'+ api.expando +'--'; if( api.isArray(data) ){ // multipart xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=_'+api.expando); data = data.join('') +'--_'+ api.expando +'--';
/** @namespace xhr.sendAsBinary https://developer.mozilla.org/ru/XMLHttpRequest#Sending_binary_content */ if( xhr.sendAsBinary ){ xhr.sendAsBinary(data); } else { var bytes = Array.prototype.map.call(data, function(c){ return c.charCodeAt(0) & 0xff; }); xhr.send(new Uint8Array(bytes).buffer); /** @namespace xhr.sendAsBinary https://developer.mozilla.org/ru/XMLHttpRequest#Sending_binary_content */ if( xhr.sendAsBinary ){ xhr.sendAsBinary(data); } else { var bytes = Array.prototype.map.call(data, function(c){ return c.charCodeAt(0) & 0xff; }); xhr.send(new Uint8Array(bytes).buffer);
} } else { // FormData xhr.send(data); } } else { xhr.send(data); } } } }; Expand Down