I have a function that allows me to pass file content, name, and type and the function will automatically save it. It works great for text based documents, but now I'm trying to have it save other files, like an image file. Somewhere along the line its getting corrupted and isn't working.
function write(text, filename, mime){
var file = new Blob([text], {type:mime}), a = document.createElement('a');
// Download in IE
if(window.navigator.msSaveBlob) window.navigator.msSaveBlob(file, filename);
// Download in compliant browsers
else{
var url = URL.createObjectURL(file);
a.href = url, a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function(){
document.body.removeChild(a);
window.URL.revokeObjectURL(url);}, 0);}}
write('Plain text', 'demo.txt', 'text/plain');
write(atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAAdCAIAAADkY5E+AAAAD0lEQVR42mNg0AthoDMGAE1BDruZMRqXAAAAAElFTkSuQmCC'), 'demo.png', 'image/png');
FileSaver.js a very powerfull js script to save any type of blob file.
Import it then use it like that:
saveAs(new Blob([file], {type:mime}),filename);
Are you fetching the file using ajax? if so, you should set
XmlHttpRequest.responseType to 'arraybuffer' or 'blob' (default is '' and that will not work with binaries or blob data).
Working example (using arraybuffer) (Fiddle):
var xhr = new XMLHttpRequest();
var url = 'https://upload.wikimedia.org/wikipedia/commons/d/da/Internet2.jpg';
xhr.responseType = 'arraybuffer'; //Set the response type to arraybuffer so xhr.response returns ArrayBuffer
xhr.open('GET', url , true);
xhr.onreadystatechange = function () {
if (xhr.readyState == xhr.DONE) {
//When request is done
//xhr.response will be an ArrayBuffer
var file = new Blob([xhr.response], {type:'image/jpeg'});
saveAs(file, 'image.jpeg');
}
};
xhr.send(); //Request is sent
Working example 2 (using blob) (Fiddle):
var xhr = new XMLHttpRequest();
var url = 'https://upload.wikimedia.org/wikipedia/commons/d/da/Internet2.jpg';
xhr.responseType = 'blob'; //Set the response type to blob so xhr.response returns a blob
xhr.open('GET', url , true);
xhr.onreadystatechange = function () {
if (xhr.readyState == xhr.DONE) {
//When request is done
//xhr.response will be a Blob ready to save
saveAs(xhr.response, 'image.jpeg');
}
};
xhr.send(); //Request is sent
I recommend FileSaver.js to save the blobs as files.
Useful links:
XmlHttpRequest Standard
XmlHttpRequest Standard (responseType attribute)
MDN Docs (XmlHttpRequest)
MDN Docs (ArrayBuffer)
Related
I am using Bing Maps where you can use a POST call to get image data (png/jpeg/gif).
https://learn.microsoft.com/en-us/bingmaps/rest-services/imagery/get-a-static-map
Neither can I render the image to the user nor is it possible to download the file and display it when opened locally (the download works but the image file won't show an image).
This is the code that handles the image data from the POST request to the bing maps api:
// rsp contains UTF-8 image data (png)
let reader = new FileReader();
let file = new File([rsp], 'test.png');
// trying to render to user
reader.onloadend = function () {
document.getElementById('img').src = 'data:image/png;base64,' + reader.result.substr(37); // substr(37) will get base 64 string in a quick and dirty way
};
reader.readAsDataURL(file);
// trying to make the image downloadable (just for testing purposes)
var a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.text = "Test";
a.download = 'test.png';
document.body.appendChild(a);
The solution was to use a native XMLHttpRequest with responseType 'blob' or 'arraybuffer' to handle the binary server response (https://stackoverflow.com/a/33903375/6751513).
var request = new XMLHttpRequest();
request.open("POST", bingMapsPOSTEndpoint + '&' + queryParamsString, true);
request.responseType = "blob";
request.onload = function (e) {
var dataURL = URL.createObjectURL(request.response);
document.getElementById('img').src = dataURL;
};
request.send();
Can you please tell me how can I correctly store some js file to localstorage and then run it.
So I have found some code that stores an image, but can I store a js file?
Here is the code:
https://gist.github.com/robnyman/1875344
// Getting a file through XMLHttpRequest as an arraybuffer and creating a Blob
var rhinoStorage = localStorage.getItem("rhino"),
rhino = document.getElementById("rhino");
if (rhinoStorage) {
// Reuse existing Data URL from localStorage
rhino.setAttribute("src", rhinoStorage);
}
else {
// Create XHR and FileReader objects
var xhr = new XMLHttpRequest(),
fileReader = new FileReader();
xhr.open("GET", "rhino.png", true);
// Set the responseType to blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
// onload needed since Google Chrome doesn't support addEventListener for FileReader
fileReader.onload = function (evt) {
// Read out file contents as a Data URL
var result = evt.target.result;
// Set image src to Data URL
rhino.setAttribute("src", result);
// Store Data URL in localStorage
try {
localStorage.setItem("rhino", result);
}
catch (e) {
console.log("Storage failed: " + e);
}
};
// Load blob as Data URL
fileReader.readAsDataURL(xhr.response);
}
}, false);
// Send XHR
xhr.send();
}
I have Java REST webservice that returns documents as byte array, I need to write JavaScript code to get the webservice's response and write it to a file in order to download that file as PDF Kindly see a screen shot of the webservice's response and see my sample code this code downloads a corrupted PDF file.
var data = new FormData();
data.append('PARAM1', 'Value1');
data.append('PARAM2', 'Value2');
var xhr = new XMLHttpRequest();
xhr.open('POST', 'SERVICEURL');
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "Basic " + btoa("username:password"));
xhr.onload = function() {
console.log('Response text = ' + xhr.responseText);
console.log('Returned status = ' + xhr.status);
var arr = [];
arr.push(xhr.responseText);
var byteArray = new Uint8Array(arr);
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob(byteArray, { type: 'application/octet-stream' }));
a.download = "tst.pdf";
// Append anchor to body.
document.body.appendChild(a)
a.click();
// Remove anchor from body
document.body.removeChild(a)
};
xhr.send(data);
Since you are requesting a binary file you need to tell XHR about that otherwise it will use the default "text" (UTF-8) encoding that will interpret pdf as text and will mess up the encoding. Just assign responseType property a value of 'blob' or the MIME type of pdf
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob'; // tell XHR that the response will be a pdf file
// OR xhr.responseType = 'application/pdf'; if above doesn't work
And you will access it using response property and not responseText.
So you will use arr.push(xhr.response); and it will return you a Blob.
If this doesn't work, inform me will update another solution.
Update:
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob'; // tell XHR that the response will be a pdf file
xhr.onload = function() {
var blob = this.response;
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = "tst.pdf";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
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
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.