Synchronous XMLHttpRequest to download a video - javascript

I would like to download completely a mp4 video from an Ajax request in order to render it later.
With an asynchronous request, it works correctly :
const req = new XMLHttpRequest();
req.open('GET', myVideoUrl, true);
req.responseType = 'blob';
req.onload = function() {
renderVideo(URL.createObjectURL(this.response));
};
But I would prefer to do it synchronously in order to block the rendering until the video is downloaded. I tried this way, but it doesn't work...
const req = new XMLHttpRequest();
req.open('GET', myVideoUrl, false);
req.send(null);
const blob = new Blob([req.responseText], { type: 'video/mp4' });
renderVideo(URL.createObjectURL(blob));
I think the problem comes from the binary data and the conversion I tried from responseText to objectUrl...
Any idea to resolve that ?

Related

Use xhr.overrideMimeType but get server response first?

I want to get a Base64 encoded file from the server in order to use it in a dataURL so I use:
xhr.overrideMimeType("text/plain; charset=x-user-defined");
So I get the unprocessed data to perform the base64 encoding on.
But I also want to get the mimetype originally returned from the server to declare my dataURL:
var dataUrl = 'data:'+mimetype+';base64,'+b64;
when I try something like the following:
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
var mimetype = xhr.getResponseHeader('content-type');
xhr.overrideMimeType("text/plain; charset=x-user-defined");
xhr.send(null);
the content-type returned is always null
Full source:
function getFileDataUrl(link,mimetype)
{
var url = location.origin+link;
var getBinary = function (url)
{
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
if(mimetype == null)
{
mimetype = xhr.getResponseHeader('content-type');
console.log('mimetype='+mimetype);
}
xhr.overrideMimeType("text/plain; charset=x-user-defined");
xhr.send(null);
return xhr.responseText;
};
var bin = getBinary(url);
var b64 = base64Encode(bin);
var dataUrl = 'data:'+mimetype+';base64,'+b64;
return dataUrl;
}
var dataUrl = getFileDataUrl(link,null);
You can set responseType of XMLHttpRequest to "blob" or "arraybuffer" then use FileReader, FileReader.prototype.readAsDataURL() on response. Though note, onload event of FileReader returns results asynchronously. To read file synchronously you can use Worker and FileReaderSync()
var reader = new FileReader();
reader.onload = function() {
// do stuff with `reader.result`
console.log(reader.result);
}
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
reader.readAsDataURL(xhr.response);
}
xhr.send(null);
At chromium synchronous XMLHttpRequest() is deprecated, see https://xhr.spec.whatwg.org/.
You can use Promise at main thread to get data URI of requested resource using either Worker or when FileReader load event is dispatched. Or use synchronous XMLHttpRequest() and FileReaderSync() at Worker thread, then listen for message event at main thread, use .then() to get Promise value.
Main thread
var worker = new Worker("worker.js");
var url = "path/to/resource";
function getFileDataUrl(url) {
return new Promise(function(resolve, reject) {
worker.addEventListener("message", function(e) {
resolve(e.data)
});
worker.postMessage(url);
})
}
getFileDataUrl(url)
.then(function(data) {
console.log(data)
}, function(err) {
console.log(err)
});
worker.js
var reader = new FileReaderSync();
var request = new XMLHttpRequest();
self.addEventListener("message", function(e) {
var reader = new FileReaderSync();
request.open("GET", e.data, false);
request.responseType = "blob";
request.send(null);
self.postMessage(reader.readAsDataURL(request.response));
});
plnkr http://plnkr.co/edit/gayWpkTVydmKYMnPr3jD?p=preview

How to use xmlhttprequest in Firefox with binary data, f.e. images?

I'm currently looking at
function readDataFromURL(fuFullHttpURL, fuCallMeOnLoad) {
var MyThis = this;
this.fullHttpURL = fuFullHttpURL;
this.callMeOnLoad = fuCallMeOnLoad;
var oReq = new XMLHttpRequest();
oReq.open("GET", MyThis.fullHttpURL, true);
oReq.responseType = "arraybuffer";
oReq.onload = function(oEvent) {
var blob = new Blob([oReq.response], {type: "image/jpg"});
MyThis.callMeOnLoad(blob);
};
oReq.send();
}
But that is only for download. How do I upload with this code?
And when I tried downloading an image with xmlhttprequest in former years there was a size restriction to the download. Is there still a size restriction?
In former times every browser handeled this size-restriction differently, so I can't test this myself.
Edit: https://stackoverflow.com/a/18120473/3716796 seems to explain uploading.
You can use FormData to send files in XMLHttpRequest like below . Although Chrome & FF support it well, it works only in IE10 or above.
var xhr = new XMLHttpRequest();
var file = document.getElementById("fileUpload");
var formData = new FormData();
formData.append("upload", file.files[0]);
xhr.open("post", "your-url", true);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.upload.onload = function(event){
// handle successful upload
};
xhr.send(formData);

Download a file with JS

I'm trying to download a remote mp3 file using JavaScript, but the problem is that I receive a cross origin error.
Here's my code:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
var blob = new Blob([xhr.response], {type: 'audio/mpeg'});
var b64data = btoa(blob);
zipFile.file(name, b64data, {base64: true});
callback();
};
xhr.send();
It's an mp3 file so I don't care about not sending cookies or such.
Is it possible?
Thanks

Excuting function after window.location.href download

i have a file download that is being initiated with a simple window.location.href command. Since i am staying on the same page i would like to call a different function that will refresh a part of the page, but this other function is not being executed after the download. Is there a way to do this?
I guess Im looking for something like ajax`s "success" option.
Thanks!
Try this:
var req = new XMLHttpRequest();
req.open("POST", "your endpoint", true);
req.responseType = "blob";
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
var fileName = "fileName.pdf";
req.onload = function (event) {
var blob = req.response;
if (req.status === 200) {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
//call your method her to do anything
}
};
req.send();
//if you have any parameter, you can this
//reg.send(param)
A simple AJAX post call would suffice. Especially with something async and variable in time like a file download, the readyState attribute of an XMLHttpRequest is quite helpful.

fetch filepicker file into arraybuffer in web browser

I'm trying to use filepicker.io to fetch binary data and pass it into a function like this:
var doSomething = function(arrayBuffer) {
var u16 = new Int16Array(arrayBuffer);
}
I have no idea how to convert the binary into arraybuffer like this:
filepicker.getContents(url, function(data){
//convert data into arraybuffer
}
I tried to follow this tutorial on XMLHttpRequest but does't not work.
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
doSomething(this.response);
};
You are not calling .send with your XHR
xhr.send(null);

Categories