I have an app that converts files. I'm sending a file, and the converted file is being returned in the form of a data URL. Had everything working great in Chrome, but IE (10/11/Edge) is a different story. Have tried several things to no prevail:
1) HTML5 download attribute is not supported in IE. I tried assigning the returned URL as an anchor tag href, but invoking .click() is not supported, and manually clicking on the link does nothing.
2) window.navigator.msSaveOrOpenBlob() and File Saver.js. The SaveAs dialog pops up, but the blob is empty and never downloads anything.
var file= new Blob([returnedFile], {type: "application/pdf"});
window.navigator.msSaveOrOpenBlob(file, 'doc.pdf');
FileSaver.saveAs(file, 'doc.pdf');
Any ideas or suggestions to try?
First, try to verify saveAs existance:
if (window.saveAs) {
window.saveAs(blob, name);
} else {
navigator.saveBlob(blob, name);
}
As for the Blob itself:
create <a>
update href:
a.href = window.URL.createObjectURL(new Blob(returnedFile, {type: "application/pdf"}));
fire click event
More or less the same functionality can be reviewed there: http://jsfiddle.net/VB59f/2/
Ended up getting the browser via navigator.userAgent.match and handling the save based on each browser accordingly:
var saveData = (data, fileName) => {
IE:
FileSaver.saveAs(blob, fileName + "." + extension);
Chrome:
var downloadLink = document.createElement("a");
document.body.appendChild(downloadLink);
downloadLink.style.display = "none";
downloadLink.href = data;
downloadLink.download = fileName;
downloadLink.click();
Related
I am trying to create a button that triggers a download of a JSON file. (And please i don't want to use any libraries to achieve this). Thank you.
import Data from '../Data';
let data = Data;
<Button>Download</Button>
Triggering browser download from front-end is not reliable.
What you should do is, create an endpoint that when called, will provide the correct response headers, thus triggering the browser download.
Front-end code can only do so much. The 'download' attribute for example, might just open the file in a new tab depending on the browser.
Take a look at this solution: How to create a file in memory for user to download, but not through server? I have rewritten their code a bit, but basically for your case, you'd want...
// Set globals
var mimetype = 'application/json';
var filename = 'yourfile.json';
// Create Dummy A Element
var a = window.document.createElement('a');
// createObjectURL for local data as a Blob type
a.href = window.URL.createObjectURL(new Blob([data], {
encoding: "UTF-8",
type: mimetype + ";charset=UTF-8",
}));
a.download = filename;
// Download file and remove dummy element
document.body.appendChild(a);
a.click();
a.remove();
You would need to create a file using your data and then create a downloadable link
and append it in whichever part of your application you would like to.
const fileName = "file";
const json = JSON.stringify(data);
const blob = new Blob([json],{type:'application/json'});
const href = await URL.createObjectURL(blob); // Create a downloadable link
const link = document.createElement('a');
link.href = href;
link.download = fileName + ".json";
document.body.appendChild(link); // This can any part of your website
link.click();
document.body.removeChild(link);
I have a plain text variable which I want to store and save on a .txt file using Angular.
So far I have tried the following:
var data = new Blob([text], {type: 'text/plain'});
const url= window.URL.createObjectURL(data);
window.open(url);
Being text the variable with the plain text content. It seems to work but it opens de blob on a new browser tab, and I need it to be downloaded as whatever.txt.
How can I achieve this? Thanks!
The solution can be found here:
JavaScript blob filename without link
The steps are the following:
Create a hidden <a> tag.
Set its href attribute to the blob's URL.
Set its download attribute to the filename.
Click on the <a> tag.
This is working code from my application
const file = new window.Blob([data], { type: contentType });
const downloadAncher = document.createElement("a");
downloadAncher.style.display = "none";
const fileURL = URL.createObjectURL(file);
downloadAncher.href = fileURL;
downloadAncher.download = fileName;
downloadAncher.click();
I have codes below to generate the download link so that users could download the .csv file on my site.
var link = document.createElement("a");
link.id = "csvDwnLink";
window.URL = window.URL || window.webkitURL;
var csv = "\ufeff" + CSV,
blob = new window.Blob([csv], {type: 'text/csv, charset=UTF-8'}),
csvUrl = window.URL.createObjectURL(blob),
filename = 'export.csv';
$("#csvDwnLink").attr({'download': filename, 'href': csvUrl});
$('#csvDwnLink')[0].click();
document.body.removeChild(link);
I hope the user could click the download link with csvUrl to download the cvs file.
It works on chrome. However, when I click the same link using Safari, it will directly show me the content of the csv file in the tab.
How do I solve this problem so that the safari will show the saving file window which user could select the path where they want to save the file instead of showing the content of the cvs file directly when I click the download link?
Hope someone could me some recommendations or alternative methods.
Thanks in advance!
== Updated ==
Find out solutions here
solution 1,
solution 2
The code will be:
var link = document.createElement("a");
link.id = "csvDwnLink";
document.body.appendChild(link);
window.URL = window.URL || window.webkitURL;
var csv = "\ufeff" + CSV,
csvData = 'data:attachment/csv;charset=utf-8,' + encodeURIComponent(csv),
filename = 'filename.csv';
$("#csvDwnLink").attr({'download': filename, 'href': csvData});
$('#csvDwnLink')[0].click();
document.body.removeChild(link);
Safari will download the file for the user, however, the file name will be unknown, probably it's because Safari don't support 'download' attribute yet as raphael mentioned.
I did a quick research - I looks like Safari does not support what you are trying to achieve.
The reason why your solution works in Chrome (and Firefox) is that they support the download attribute - Safari doesn't yet.
Safari 10.1+ supports "download" attribute. It should work now.
https://github.com/eligrey/FileSaver.js/issues/129#issuecomment-275221240
I use javascript to generate a file and download it.
It seems, that depending on the version of chrome, the download file names can be auto renamed to 'download'. Is there a way to avoid it?
this is my code:
var link = document.createElement("a");
link.setAttribute("href", 'data:application/octet-stream,' + 'file content here');
link.setAttribute("download", 'file1.txt');
link.click();
This is not a duplicated question, because I'm using the latest Chrome and the previously suggested hyperlink is exactly what I'm using. I think, Chrome v34 works fine, but once my Chrome auto updated to v35, it went back to 'download' file name.
It seems to be linked to this bug/feature. Status: Wontfix.
Use HTML5 download attribute. This attribute will tell browser that virtual link we created is aimed for download only. It will download file from link's href to file with name specified as download attribute's value. This great feature works in Chrome.
window.downloadFile = function(sUrl) {
//If in Chrome or Safari - download via virtual link click
if (window.downloadFile.isChrome || window.downloadFile.isSafari) {
//Creating new link node.
var link = document.createElement('a');
link.href = sUrl;
if (link.download !== undefined){
//Set HTML5 download attribute. This will prevent file from opening if supported.
var fileName = sUrl.substring(sUrl.lastIndexOf('/') + 1, sUrl.length);
link.download = fileName;
}
//Dispatching click event.
if (document.createEvent) {
var e = document.createEvent('MouseEvents');
e.initEvent('click' ,true ,true);
link.dispatchEvent(e);
return true;
}
}
// Force file download (whether supported by server).
var query = '?download';
window.open(sUrl + query);
}
window.downloadFile.isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
window.downloadFile.isSafari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;
Demo Link: http://pixelscommander.com/polygon/downloadjs/#.U4gyDPmSwgS
I'm trying to save a SVG from a canvas as PNG file using javascript.
The below code seems to work fine on Chrome and Firefox, but in IE 10 i get the below error in my console.
SCRIPT5: Access is denied.
FInd below the code that I've used:
var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
var a = $('<a>').attr("href", canvas.toDataURL("image/png")).attr("download", title + "png").appendTo($('#VisitsContainer'));
a[0].click();
a.remove();
The console points to the click event that I'm trying to invoke.
The download attribute is not implemented in Internet Explorer.
http://caniuse.com/download
For Internet explorer you can use the "SaveAs" command.
A note about security:
Browsers serve 2 masters.
Browsers must serve the user's request to save content to their local drive.
Browsers must also restrict potentially malicious code from automatically downloading bits onto the users local drive.
To reconcile the 2 tasks, browsers take the approach that users can download content to their local drive after some confirming process (like a Save button).
Using a[0].click(); to confirm for the user runs contrary to the browser's attempt to provide security.
FileSave.js is a cross-browser library that will save your canvas to the users local drive. It conforms to security issues by requiring the user to click a button to OK the download.
https://github.com/eligrey/FileSaver.js/
Necromancing.
On IE, you don't need to create a link.
It's sufficient to create a new Blob.
function saveMe(data, fileName)
{
var json = JSON.stringify(data),
blob = new Blob([json], { type: "octet/stream" }),
url = window.URL.createObjectURL(blob);
if (navigator.msSaveOrOpenBlob)
{
navigator.msSaveOrOpenBlob(blob, fileName);
return;
}
else if (window.navigator.msSaveBlob)
{ // for IE browser
window.navigator.msSaveBlob(blob, fileName);
return;
}
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}
var data = { x: 42, s: "hello, world", d: new Date() }, fileName = "my-download.json";
// saveData(data, fileName);
saveMe(data, fileName);