I am trying to download a file in a service worker. The file came from a blob.
I already know that i can download a blob by doing this
var urlCreator = window.URL || window.webkitURL;
var blobURL = urlCreator.createObjectURL(blob, { type: "octet/stream" });
or by using something like FileSaver.js
But today, i am trying to "render" the bytes array of the blob in the page and force the browser to download the document.
Why ?
I am trying to do that because, some browser that i am trying to reach do not support url like "blob:https:......"
So i try to find a way to render the bytearrays of my blob directly in javascript.
I know that i can push headers with worker, but not sure that is the right strategie.
I also try something like that
var xhr = new XMLHttpRequest();
xhr.open('GET', obj.URL, false);
xhr.overrideMimeType("application/octet-stream");
//xhr.setRequestHeader("Accept", "application/octet-stream");
xhr.responseType = "arraybuffer";
xhr.onload = function (e) {
self.Response(xhr.response);
//if (this.status == 200) {
// var myBlob = this.response;
// // myBlob is now the blob that the object URL pointed to.
//}
};
xhr.send();
In my worker.js
ps: Please avoid to told me, send you base64 blob content to your server and send back the file to the browser, i would like to find a pure javascript solution.
Is it possible ?
Related
I'm trying to create a web application for videos, I decided to start by configuring the videos, in case of problem, creating blob url for videos.
It turns out that I'm not sure what terms to use to search in google and the ones I used do not find anything very simple or straightforward.
I would like to know how I can create a blob url for videos and what would be the best way, since I have already seen topics using FileReader and MediaSource and some others, so I would like to know the simplest way to do this.
I'm testing on a direct html, without external libraries or external files.
var URL = this.window.URL || this.window.webkitURL;
var file = new Blob(["http://localhost/assets/mp4/video.mp4"],{"type" : "video\/mp4"});
var value = URL.createObjectURL(file);
$(document).ready(function(){
$('#MyVideo').attr('src',value);
});
Generates a blob link but does not load the video
Edit:
For further questions from beginners like me, I got the expected result with the script below:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost/assets/mp4/video.mp4');
xhr.responseType = 'arraybuffer';
xhr.onload = function(e){
var blob = new Blob(([xhr.response]));
var url = URL.createObjectURL(blob);
document.getElementById('_video').src = url;
};
Supposing I want to upload a stream of random data from my browser to a remote server. I would use something like
var oReq = new XMLHttpRequest();
oReq.open("POST", url, true);
oReq.onload = function (oEvent) {
// Uploaded.
};
var blob = new Blob(['abc123'], {type: 'text/plain'});
oReq.send(blob);
and repeat this as many times as I have chunks to upload.
But, what if I wanted to send it using a single XHR request ? Is it possible to override the Blob function and do something like
function Blob(arr, options) {
var chunkSize = 1024;
MyBlob.prototype.nextChunk(function () {
return arr.splice(0, chunkSize);
});
}
I know that nextChunk does not exist, obviously, but maybe there is some interface that can be overridden ? I looked at the Blob specification and I tried using an alternative Blob implementation (that I modified slightly to force overriding window.Blob), but nothing was sent to the server.
I am trying to download a file using jQuery. The problem is I have no reference about the file extension. I only know the file name. The file name is unique because it shares the same name with the primary key. So, no file is the same.
This is the jQuery I use:
$("#tbl_surat_all tbody").on('click','.row_surat', function(e) {
var no_s = $(this).find('a').html(); //get the file name
var b_url = $('#base_url').val()+"assets/uploads/surat/"; //base_url
var url = b_url+no_s; //download_url
window.location = url; //script_to_download
});
How do I download the file by only knowing the file name??
Note:
I have no privilage to change table structure, so I can't update the upload script.
The file are images, pdfs, and rars
There is no way to open the file from the server without sending a valid request.
If you don't request the complete file name with extension, you will get an error.
So the only workaround would be to request all possible file extensions.
We could try to include the following:
.jpeg .jpg .png .pdf .rar
And then iterate it with requests.
Since this would open a **** load of windows, we will be immediately closing them, so it will look relatively smooth.
Here is the code:
var url_base='http://127.0.0.1/base_url/file_without_extension';
var ext_arr=['.jpeg', '.jpg', '.png', '.pdf', '.rar'];
for (i=0;i<ext_arr.length;i++){
var url=url_base+ext_arr[i];
window.open(url)
.addEventListener('load', function(){
this.close();
}, false);
}
Note: do note that in order for it work properly, requested files must meet the same origin policy.
Edit: I have modified the above code to load resources in background via xhttp requests and then output it directly for download.
This method should work flawlessly for all types of files, and it's also the fastest!
var url_base='http://127.0.0.1/';
var file_name='file_without_extension';
var ext_arr=['.jpeg', '.jpg', '.png', '.pdf', '.rar'];
for (i=0;i<ext_arr.length;i++){
// Define request url
var url=url_base+file_name+ext_arr[i];
// Use XMLHttpRequest instead of Jquery $ajax
var xhttp = new XMLHttpRequest();
// Set the url as a property
xhttp['user_filename']=file_name;
// Bind on ready function
xhttp.onreadystatechange = function() {
var a;
// Check if page has loaded successfully
if (this.readyState === 4 && this.status === 200) {
// Trick for making downloadable link
a = document.createElement('a');
a.href = window.URL.createObjectURL(this.response);
// Filename for downloading
a.download = this.user_filename;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
a.parentNode.removeChild(a);
}
};
// Set request url and method
xhttp.open("GET", url);
// Set responseType as blob for binary response
xhttp.responseType = 'blob';
// Send request
xhttp.send();
}
I have a webworker that is producing a CSV for downloading, and to conserve memory I only have it return the URL it produces from teh blob..
My worker code looks something like::
var blob = new Blob([ResultOfSomeWork()],{type:'text/csv'});
URL.createObjectURL(blob);
self.postMessage({url:blob.url});
My goal is to just be able to download it in firefox and chrome this is very easy as I can just set up an invisible <a> and have it be clicked to download it.
For IE10 I want to use msSaveBlob but I need a blob which I don't want to transfer.
How can I download a object dataurl in IE10?
So I found a solution that works. Apparently, I can XHR and read the content back in my main thread.
worker.onmessage = function(event){
var url = event.data.url;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType='blob';
xhr.onload = function(){
msSaveBlob(xhr.response, fileName +'.csv');
};
xhr.send();
}
While this feels extremely complicated it works well in practice and is really fast.
I'm trying to upload a blob URL generated by getUserMedia to the server.
Someone else wanted to do the same thing, and that question has been answered.
I am using the same code for the XHR request as the person who answered that question, but I'm getting a 404. I made a fiddle, and the same thing happens when you look at the console. I have a live example on my site as well, and the same thing happens.
Here is the piece of code that needs some TLC:
function XHR(){
var xhr = new XMLHttpRequest();
xhr.open('GET',record.src); //404 ???
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200){
//do some stuff
result.innerText = this.response;
}
};
xhr.send();
}
Everybody else seems to be able to do this, because this has been discussed before.
Exhibit A
Exhibit B
I'm using ChromeOS, 41.0.2252.2 dev. What exactly is going on, and why can't I get the blob?
I'm almost certain the media in a MediaStream isn't saved anywhere, just thrown away after use.
There is a API in the works to record streams, MediaRecorder .
Only Firefox has the most basic implementation of this so it isn't usable as yet.
If you're implementing this on a mobile device you can use a file input with the capture attribute.
<input type="file" accept="video/*" capture>
function XHR(){
var xhr = new XMLHttpRequest();
xhr.open("GET","record.src",true); // adding true will make it work asynchronously
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200){
//do some stuff
result.innerText = this.response;
}
};
xhr.send();
}
Try now! it should work.
look at this post:
Html5 video recording and upload?
What you are missing is the declaration of what "blob" is. First thing this person does inside the .onload function() is
var blob = new Blob([this.response], {type: 'video/webm'});