
Question:
The extension crashes when it executes such code:
/*this object is created in content script and passed t background script*/
var myurl = URL.createObjectURL(document.getElementById('myfile').files[0]);
/*code block from background script, it work good if file size is < 50MB, if bigger then extension will crash*/
var x = new XMLHttpRequest();
x.onload = function() {
var uploadfile = new Uint8Array(x.response);
var somearray1 = [...];
var somearray2 = [...];
var size = somearray1.length + uploadfile.length + somearray2.length;
var u8array = new Uint8Array(size);
var i = 0;
for (i = 0; i < somearray1.length; i++)
u8array[i] = somearray1.charCodeAt(i) & 0xff;
for (var j = 0; j < uploadfile.length; i++, j++)
u8array[i] = ufile[j];
for (i = 0; i < somearray2.length; i++)
u8array[i] = somearray2.charCodeAt(i) & 0xff;
var req = new XMLHttpRequest();
req.open("POST", Url);
req.setRequestHeader("Content-Type", 'multipart/form-data; boundary=--_BOUNDARY_');
req.send(u8array);
};
x.open('GET', myurl);
x.responseType = 'arraybuffer';
x.send();
I want to upload a file of 200MB size, and it crashes the extension. Please help me understand with some sample code how to upload it correctly if it is wrong the way i'm doing now.
Answer1:Your extension crashes because it runs out of memory due to your inefficient way of uploading data.
You should not load the file in memory, but pass the file object to XMLHttpRequest so that Chrome can stream the file contents in the upload form. This can be done with the <a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData" rel="nofollow">FormData
</a> object.
The easiest way of doing this is to upload the form in a content script instead of a background page, because it is not easy to pass a File
to the background.
// In a content script:
var myfile = document.getElementById('myfile').files[0];
var form = new FormData();
form.append('myfile', myfile);
// Add more key-value pairs using form.append(...key..., ...value...);
// Upload
var x = new XMLHttpRequest();
x.open('POST', 'http://example.com/');
x.send(form);
This is all it takes to stream files through XMLHttpRequest. The FormData
object will be serialized and uploaded using the multipart/form-data algorithm. For more details, see <a href="http://www.w3.org/TR/XMLHttpRequest2/#the-send-method" rel="nofollow">http://www.w3.org/TR/XMLHttpRequest2/#the-send-method</a>.
If you don't want to upload in a content script (because you want the upload to continue even after the page closes, then you have to pass the File
object to the background page via a Shared Worker (that acts as a trampoline). If you want to learn more about this option, read <a href="https://stackoverflow.com/questions/21086918/does-chrome-runtime-support-posting-messages-with-transferable-objects/21101597#21101597" rel="nofollow">Does chrome.runtime support posting messages with transferable objects?</a>.