Downloading a Dynamic CSV in Internet Explorer - javascript

The following code works in both FireFox and Chrome, but not IE. Essentially, I have a JSON object which gets converted into an array and then to a csv format, when I click the button in FF or Chrome the file gets downloaded or the Save As window opens, but in IE a new tab opens up. In a perfect world IE would not exists, but in the real world we have to make it work, lol.
$("#csvbtn").click(function(e){
e.preventDefault();
var json_obj= JSON.parse(result);
var csv = JSON2CSV(json_obj);
window.open("data:text/csv;charset=utf-8," + escape(csv));
});
BTW, I am using IE 11 in windows 8 to test this, if that makes a difference.
Thanks all!

This is my solution in case someone else is looking for a solution. now it works with FF, Chrome , and IE
var csv = JSON2CSV(json_obj);
var blob = new Blob([csv],{type: "text/csv;charset=utf-8;"});
if (navigator.msSaveBlob) { // IE 10+
navigator.msSaveBlob(blob, "csvname.csv")
} else {
var link = document.createElement("a");
if (link.download !== undefined) { // feature detection
// Browsers that support HTML5 download attribute
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", "csvname.csv");
link.style = "visibility:hidden";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
Now I just need to figure out if there is a way to have the save as screen pop up instead of automatically saving the file. If anybody knows the answer to that please share. For now my users will have to use this functionality.
Thanks all for all the great answers, you guys are awesome.

Internet Explorer does not permit data URIs as navigable content, for security purposes. To understand why, I would encourage you to read Henning Klevjer's short white-paper on the topic, Phishing by data URI. In summary, this has been demonstrated to open up avenues by which the end-user could be tricked into giving up sensitive information.
Also, from the data Protocol documentation on MSDN:
For security reasons, data URIs are restricted to downloaded resources. Data URIs cannot be used for navigation, for scripting, or to populate frame or iframe elements.
To be honest, passing a data URI to window.open feels a bit hacky. Instead, you should use an API to handle the process (provided one exists). If you'd like to download a file to the user's machine in Internet Explorer, consider using navigator.msSaveBlob or navigator.msSaveOrOpenBlob.
As an example, consider the following:
if ( window.navigator.msSaveOrOpenBlob && window.Blob ) {
var blob = new Blob( [ "A,B\nC,D" ], { type: "text/csv" } );
navigator.msSaveOrOpenBlob( blob, "strings.csv" );
}

Related

IE + XMLHttp + CreateObjectURL Error

I am trying to download and show the contents of a remote file inside an iFrame , and succeeded in all browsers except for IE(i am trying with IE 10).
I have used XMLHttpRequest,Blob,CreateOBjectUrl APIs to complete the process.
In IE i am not able to view the file content inside the iFrame and also no particular error messages appeared on console as well.
I had pasted my code at the bottom of this thread , and a step by step explanation as below
Getting the download document url & corresponding mime
type(Perfectly fine in all broswers).
Invoking XMLHttp Request , a
Http GET Async call ,as response type as 'arraybuffer' (Perfectly
fine in all browsers) Upon completing the XMLHttpGet below 3 steps are
executing.
Creating a blob using the proper mimetype ;(Perfectly fine in all other browsers, specially verified the blob by downloading it in IE using MSSaveOrOpenBlob method).
4.InOrder to bind the blob contents to the iFrame , create the blob url using "createObjectURL" (Perfectly fine in all browsers , but in IE we are not getting a perfect URL).
Finally binding the URL with the iFrame for display.
Code snippet below.
// Getting the document url and mime type ( Which is perfectly fine )
var downloadUrl=finalServerURL + "DocumentService.svc/GetItemBinary?id=" + itemId + "&version=" + version;
var mimeTypeForDownload = responseStore.mimeTypes[currentlySelectedObject.fileExtension];
window.URL = window.URL || window.webkitURL;
//Defining the XML Http Process
var xhr = new XMLHttpRequest();
xhr.open('GET', downloadUrl, true);
xhr.responseType = 'arraybuffer'; //Reading as array buffer .
xhr.onload = function (e) {
var mimeType = mimeTypeForDownload;
var blob = new Blob([xhr.response], { type: mimeType });
// Perfect blob, we are able to download it in both IE and non-IE browsers
//This below url from createObjectURL,
//Working perfectly fine in all non-IE browsers, but nothing happening in IE
var url = window.URL.createObjectURL(blob);
document.getElementById(documentContentiFrameId).setAttribute("src", url);
};
xhr.send;
Please let me if you get any information on this , would be really helpful.
I came to know that its not possible in IE to get a proper URL for your blob entries , none of my attempts are get succeeded.
My alternative solutions,
1)go for pdf.js , an open source javascript library , which allows to render pdf binaries and equivalent pdf blobs.
2)Write your own viewers by utilizing the open PDF libraries , which will be time consuming , and more learning efforts involved.
Thanks,
Vishnu

How to fix javascript to change image file name from "download" to something else for example "test.png"? HTML [duplicate]

If for example you follow the link:
data:application/octet-stream;base64,SGVsbG8=
The browser will prompt you to download a file consisting of the data held as base64 in the hyperlink itself. Is there any way of suggesting a default name in the markup? If not, is there a JavaScript solution?
Use the download attribute:
<a download='FileName' href='your_url'>
The download attribute works on Chrome, Firefox, Edge, Opera, desktop Safari 10+, iOS Safari 13+, and not IE11.
Chrome makes this very simple these days:
function saveContent(fileContents, fileName)
{
var link = document.createElement('a');
link.download = fileName;
link.href = 'data:,' + fileContents;
link.click();
}
HTML only: use the download attribute:
<a download="logo.gif" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Download transparent png</a>
Javascript only: you can save any data URI with this code:
function saveAs(uri, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
link.href = uri;
link.download = filename;
//Firefox requires the link to be in the body
document.body.appendChild(link);
//simulate click
link.click();
//remove the link when done
document.body.removeChild(link);
} else {
window.open(uri);
}
}
var file = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
saveAs(file, 'logo.gif');
Chrome, Firefox, and Edge 13+ will use the specified filename.
IE11, Edge 12, and Safari 9 (which don't support the download attribute) will download the file with their default name or they will simply display it in a new tab, if it's of a supported file type: images, videos, audio files, …
According to RFC 2397, no, there isn't.
Nor does there appear to be any attribute of the <a> element that you can use either.
However HTML5 has subsequently introduced the download attribute on the <a> element, although at the time of writing support is not universal (no MSIE support, for example)
I've looked a bit in firefox sources in netwerk/protocol/data/nsDataHandler.cpp
data handler only parses content/type and charset, and looks if there is ";base64"
in the string
the rfc specifices no filename and at least firefox handles no filename for it,
the code generates a random name plus ".part"
I've also checked firefox log
[b2e140]: DOCSHELL 6e5ae00 InternalLoad data:application/octet-stream;base64,SGVsbG8=
[b2e140]: Found extension '' (filename is '', handling attachment: 0)
[b2e140]: HelperAppService::DoContent: mime 'application/octet-stream', extension ''
[b2e140]: Getting mimeinfo from type 'application/octet-stream' ext ''
[b2e140]: Extension lookup on '' found: 0x0
[b2e140]: Ext. lookup for '' found 0x0
[b2e140]: OS gave back 0x43609a0 - found: 0
[b2e140]: Searched extras (by type), rv 0x80004005
[b2e140]: MIME Info Summary: Type 'application/octet-stream', Primary Ext ''
[b2e140]: Type/Ext lookup found 0x43609a0
interesting files if you want to look at mozilla sources:
data uri handler: netwerk/protocol/data/nsDataHandler.cpp
where mozilla decides the filename: uriloader/exthandler/nsExternalHelperAppService.cpp
InternalLoad string in the log: docshell/base/nsDocShell.cpp
I think you can stop searching a solution for now, because I suspect there is none :)
as noticed in this thread html5 has download attribute, it works also on firefox 20 http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download
The following Javascript snippet works in Chrome by using the new 'download' attribute of links and simulating a click.
function downloadWithName(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
link.click();
}
And the following example shows it's use:
downloadWithName("data:,Hello%2C%20World!", "helloWorld.txt")
No.
The entire purpose is that it's a datastream, not a file. The data source should not have any knowledge of the user agent handling it as a file... and it doesn't.
you can add a download attribute to the anchor element.
sample:
<a download="abcd.cer"
href="data:application/stream;base64,MIIDhTC......">down</a>
Using service workers, this is finally possible in the truest sense.
Create a fake URL. For example /saveAs/myPrettyName.jpg
Use URL in <a href, <img src, window.open( url ), absolutely anything that can be done with a "real" URL.
Inside the worker, catch the fetch event, and respond with the correct data.
The browser will now suggest myPrettyName.jpg even if the user opens the file in a new tab, and tries to save it there. It will be exactly as if the file had come from the server.
// In the service worker
self.addEventListener( 'fetch', function(e)
{
if( e.request.url.startsWith( '/blobUri/' ) )
{
// Logic to select correct dataUri, and return it as a Response
e.respondWith( dataURLAsRequest );
}
});
Look at this link:
http://lists.w3.org/Archives/Public/uri/2010Feb/0069.html
Quote:
It even works (as in, doesn't cause a problem) with ;base64 at the end
like this (in Opera at least):
data:text/plain;charset=utf-8;headers=Content-Disposition%3A%20attachment%3B%20filename%3D%22with%20spaces.txt%22%0D%0AContent-Language%3A%20en;base64,4oiaDQo%3D
Also there is some info in the rest messages of the discussion.
There is a tiny workaround script on Google Code that worked for me:
http://code.google.com/p/download-data-uri/
It adds a form with the data in it, submits it and then removes the form again. Hacky, but it did the job for me. Requires jQuery.
This thread showed up in Google before the Google Code page and I thought it might be helpful to have the link in here, too.
Here is a jQuery version based off of Holf's version and works with Chrome and Firefox whereas his version seems to only work with Chrome. It's a little strange to add something to the body to do this but if someone has a better option I'm all for it.
var exportFileName = "export-" + filename;
$('<a></a>', {
"download": exportFileName,
"href": "data:," + JSON.stringify(exportData, null,5),
"id": "exportDataID"
}).appendTo("body")[0].click().remove();
This one works with Firefox 43.0 (older not tested):
dl.js:
function download() {
var msg="Hello world!";
var blob = new File([msg], "hello.bin", {"type": "application/octet-stream"});
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
window.location.href=a;
}
dl.html
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<title>Test</title>
<script type="text/javascript" src="dl.js"></script>
</head>
<body>
<button id="create" type="button" onclick="download();">Download</button>
</body>
</html>
If button is clicked it offered a file named hello.bin for download. Trick is to use File instead of Blob.
reference: https://developer.mozilla.org/de/docs/Web/API/File
(This answer has been made deprecated by newer technology, but will be kept here for historical interest.)
It's kind of hackish, but I've been in the same situation before. I was dynamically generating a text file in javascript and wanted to provide it for download by encoding it with the data-URI.
This is possible with minormajor user intervention. Generate a link right-click me and select "Save Link As..." and save as "example.txt". As I said, this is inelegant, but it works if you do not need a professional solution.
This could be made less painful by using flash to copy the name into the clipboard first. Of course if you let yourself use Flash or Java (now with less and less browser support I think?), you could probably find a another way to do this.
<a href=.. download=.. > works for left-click and right-click -> save link as..,
but <img src=.. download=.. > doesn't work for right-click -> save image as.. , "Download.jped" is suggested.
If you combine both:<a href=.. download=..><img src=..></a>
it works for left-click, right-click -> save link as.., right-click -> save image as..
You have to write the data-uri twice (href and src), so for large image files it is better to copy the uri with javascript.
tested with Chrome/Edge 88
var isIE = /*#cc_on!#*/false || !!document.documentMode; // At least IE6
var sessionId ='\n';
var token = '\n';
var caseId = CaseIDNumber + '\n';
var url = casewebUrl+'\n';
var uri = sessionId + token + caseId + url;//data in file
var fileName = "file.i4cvf";// any file name with any extension
if (isIE)
{
var fileData = ['\ufeff' + uri];
var blobObject = new Blob(fileData);
window.navigator.msSaveOrOpenBlob(blobObject, fileName);
}
else //chrome
{
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
fs.root.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
var fileData = ['\ufeff' + uri];
var blob = new Blob(fileData);
fileWriter.addEventListener("writeend", function () {
var fileUrl = fileEntry.toURL();
var link = document.createElement('a');
link.href = fileUrl;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}, false);
fileWriter.write(blob);
}, function () { });
}, function () { });
}, function () { });
}
You actually can achieve this, in Chrome and FireFox.
Try the following url, it will download the code that was used.
data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==

saving canvas locally in IE

Hi I want to save a canvas locally in IE.
var img = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
I couldn't manage to download it with following ways.
1) document.execCommand("SaveAs"..
2) window.location.href = img;
3) $.fileDownload(img); // jquery download file library-
4) canvas2image // cross domain problem.
Is there a way to save canvas locally in IE without base64 or cross domain problem? Thank you very much.
I know this is late, but I stumbled on this question in my search to do the same thing and I wanted to share a solution that's working for me.
Assuming you have a data URI already, you can create a blob and then use msSaveBlob or msSaveOrOpenBlob
Example:
dataURItoBlob = function(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: 'image/png'});
}
var blob = dataURItoBlob(uri);
window.navigator.msSaveOrOpenBlob(blob, "my-image.png");
I used this answer for a bulk of my solution.
After typing this, I realize this doesn't really help you with the cross domain issue, so it's a partial answer at best. With that, all I can say is consider using data URIs where possible, if cross domain is an issue.
Well, it looks like this doesn't work in IE either, but since you've not listed it, I'll provide an example. This uses the HTML5 download attribute (more here), and allows the user to click a link which then downloads a file.

file extension after base64 in javascript [duplicate]

If for example you follow the link:
data:application/octet-stream;base64,SGVsbG8=
The browser will prompt you to download a file consisting of the data held as base64 in the hyperlink itself. Is there any way of suggesting a default name in the markup? If not, is there a JavaScript solution?
Use the download attribute:
<a download='FileName' href='your_url'>
The download attribute works on Chrome, Firefox, Edge, Opera, desktop Safari 10+, iOS Safari 13+, and not IE11.
Chrome makes this very simple these days:
function saveContent(fileContents, fileName)
{
var link = document.createElement('a');
link.download = fileName;
link.href = 'data:,' + fileContents;
link.click();
}
HTML only: use the download attribute:
<a download="logo.gif" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Download transparent png</a>
Javascript only: you can save any data URI with this code:
function saveAs(uri, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
link.href = uri;
link.download = filename;
//Firefox requires the link to be in the body
document.body.appendChild(link);
//simulate click
link.click();
//remove the link when done
document.body.removeChild(link);
} else {
window.open(uri);
}
}
var file = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
saveAs(file, 'logo.gif');
Chrome, Firefox, and Edge 13+ will use the specified filename.
IE11, Edge 12, and Safari 9 (which don't support the download attribute) will download the file with their default name or they will simply display it in a new tab, if it's of a supported file type: images, videos, audio files, …
According to RFC 2397, no, there isn't.
Nor does there appear to be any attribute of the <a> element that you can use either.
However HTML5 has subsequently introduced the download attribute on the <a> element, although at the time of writing support is not universal (no MSIE support, for example)
I've looked a bit in firefox sources in netwerk/protocol/data/nsDataHandler.cpp
data handler only parses content/type and charset, and looks if there is ";base64"
in the string
the rfc specifices no filename and at least firefox handles no filename for it,
the code generates a random name plus ".part"
I've also checked firefox log
[b2e140]: DOCSHELL 6e5ae00 InternalLoad data:application/octet-stream;base64,SGVsbG8=
[b2e140]: Found extension '' (filename is '', handling attachment: 0)
[b2e140]: HelperAppService::DoContent: mime 'application/octet-stream', extension ''
[b2e140]: Getting mimeinfo from type 'application/octet-stream' ext ''
[b2e140]: Extension lookup on '' found: 0x0
[b2e140]: Ext. lookup for '' found 0x0
[b2e140]: OS gave back 0x43609a0 - found: 0
[b2e140]: Searched extras (by type), rv 0x80004005
[b2e140]: MIME Info Summary: Type 'application/octet-stream', Primary Ext ''
[b2e140]: Type/Ext lookup found 0x43609a0
interesting files if you want to look at mozilla sources:
data uri handler: netwerk/protocol/data/nsDataHandler.cpp
where mozilla decides the filename: uriloader/exthandler/nsExternalHelperAppService.cpp
InternalLoad string in the log: docshell/base/nsDocShell.cpp
I think you can stop searching a solution for now, because I suspect there is none :)
as noticed in this thread html5 has download attribute, it works also on firefox 20 http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download
The following Javascript snippet works in Chrome by using the new 'download' attribute of links and simulating a click.
function downloadWithName(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
link.click();
}
And the following example shows it's use:
downloadWithName("data:,Hello%2C%20World!", "helloWorld.txt")
No.
The entire purpose is that it's a datastream, not a file. The data source should not have any knowledge of the user agent handling it as a file... and it doesn't.
you can add a download attribute to the anchor element.
sample:
<a download="abcd.cer"
href="data:application/stream;base64,MIIDhTC......">down</a>
Using service workers, this is finally possible in the truest sense.
Create a fake URL. For example /saveAs/myPrettyName.jpg
Use URL in <a href, <img src, window.open( url ), absolutely anything that can be done with a "real" URL.
Inside the worker, catch the fetch event, and respond with the correct data.
The browser will now suggest myPrettyName.jpg even if the user opens the file in a new tab, and tries to save it there. It will be exactly as if the file had come from the server.
// In the service worker
self.addEventListener( 'fetch', function(e)
{
if( e.request.url.startsWith( '/blobUri/' ) )
{
// Logic to select correct dataUri, and return it as a Response
e.respondWith( dataURLAsRequest );
}
});
Look at this link:
http://lists.w3.org/Archives/Public/uri/2010Feb/0069.html
Quote:
It even works (as in, doesn't cause a problem) with ;base64 at the end
like this (in Opera at least):
data:text/plain;charset=utf-8;headers=Content-Disposition%3A%20attachment%3B%20filename%3D%22with%20spaces.txt%22%0D%0AContent-Language%3A%20en;base64,4oiaDQo%3D
Also there is some info in the rest messages of the discussion.
There is a tiny workaround script on Google Code that worked for me:
http://code.google.com/p/download-data-uri/
It adds a form with the data in it, submits it and then removes the form again. Hacky, but it did the job for me. Requires jQuery.
This thread showed up in Google before the Google Code page and I thought it might be helpful to have the link in here, too.
Here is a jQuery version based off of Holf's version and works with Chrome and Firefox whereas his version seems to only work with Chrome. It's a little strange to add something to the body to do this but if someone has a better option I'm all for it.
var exportFileName = "export-" + filename;
$('<a></a>', {
"download": exportFileName,
"href": "data:," + JSON.stringify(exportData, null,5),
"id": "exportDataID"
}).appendTo("body")[0].click().remove();
This one works with Firefox 43.0 (older not tested):
dl.js:
function download() {
var msg="Hello world!";
var blob = new File([msg], "hello.bin", {"type": "application/octet-stream"});
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
window.location.href=a;
}
dl.html
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<title>Test</title>
<script type="text/javascript" src="dl.js"></script>
</head>
<body>
<button id="create" type="button" onclick="download();">Download</button>
</body>
</html>
If button is clicked it offered a file named hello.bin for download. Trick is to use File instead of Blob.
reference: https://developer.mozilla.org/de/docs/Web/API/File
(This answer has been made deprecated by newer technology, but will be kept here for historical interest.)
It's kind of hackish, but I've been in the same situation before. I was dynamically generating a text file in javascript and wanted to provide it for download by encoding it with the data-URI.
This is possible with minormajor user intervention. Generate a link right-click me and select "Save Link As..." and save as "example.txt". As I said, this is inelegant, but it works if you do not need a professional solution.
This could be made less painful by using flash to copy the name into the clipboard first. Of course if you let yourself use Flash or Java (now with less and less browser support I think?), you could probably find a another way to do this.
<a href=.. download=.. > works for left-click and right-click -> save link as..,
but <img src=.. download=.. > doesn't work for right-click -> save image as.. , "Download.jped" is suggested.
If you combine both:<a href=.. download=..><img src=..></a>
it works for left-click, right-click -> save link as.., right-click -> save image as..
You have to write the data-uri twice (href and src), so for large image files it is better to copy the uri with javascript.
tested with Chrome/Edge 88
var isIE = /*#cc_on!#*/false || !!document.documentMode; // At least IE6
var sessionId ='\n';
var token = '\n';
var caseId = CaseIDNumber + '\n';
var url = casewebUrl+'\n';
var uri = sessionId + token + caseId + url;//data in file
var fileName = "file.i4cvf";// any file name with any extension
if (isIE)
{
var fileData = ['\ufeff' + uri];
var blobObject = new Blob(fileData);
window.navigator.msSaveOrOpenBlob(blobObject, fileName);
}
else //chrome
{
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
fs.root.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
var fileData = ['\ufeff' + uri];
var blob = new Blob(fileData);
fileWriter.addEventListener("writeend", function () {
var fileUrl = fileEntry.toURL();
var link = document.createElement('a');
link.href = fileUrl;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}, false);
fileWriter.write(blob);
}, function () { });
}, function () { });
}, function () { });
}
You actually can achieve this, in Chrome and FireFox.
Try the following url, it will download the code that was used.
data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==

Setting filename using encodeURIComponent() to let user download data file [duplicate]

If for example you follow the link:
data:application/octet-stream;base64,SGVsbG8=
The browser will prompt you to download a file consisting of the data held as base64 in the hyperlink itself. Is there any way of suggesting a default name in the markup? If not, is there a JavaScript solution?
Use the download attribute:
<a download='FileName' href='your_url'>
The download attribute works on Chrome, Firefox, Edge, Opera, desktop Safari 10+, iOS Safari 13+, and not IE11.
Chrome makes this very simple these days:
function saveContent(fileContents, fileName)
{
var link = document.createElement('a');
link.download = fileName;
link.href = 'data:,' + fileContents;
link.click();
}
HTML only: use the download attribute:
<a download="logo.gif" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Download transparent png</a>
Javascript only: you can save any data URI with this code:
function saveAs(uri, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
link.href = uri;
link.download = filename;
//Firefox requires the link to be in the body
document.body.appendChild(link);
//simulate click
link.click();
//remove the link when done
document.body.removeChild(link);
} else {
window.open(uri);
}
}
var file = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
saveAs(file, 'logo.gif');
Chrome, Firefox, and Edge 13+ will use the specified filename.
IE11, Edge 12, and Safari 9 (which don't support the download attribute) will download the file with their default name or they will simply display it in a new tab, if it's of a supported file type: images, videos, audio files, …
According to RFC 2397, no, there isn't.
Nor does there appear to be any attribute of the <a> element that you can use either.
However HTML5 has subsequently introduced the download attribute on the <a> element, although at the time of writing support is not universal (no MSIE support, for example)
I've looked a bit in firefox sources in netwerk/protocol/data/nsDataHandler.cpp
data handler only parses content/type and charset, and looks if there is ";base64"
in the string
the rfc specifices no filename and at least firefox handles no filename for it,
the code generates a random name plus ".part"
I've also checked firefox log
[b2e140]: DOCSHELL 6e5ae00 InternalLoad data:application/octet-stream;base64,SGVsbG8=
[b2e140]: Found extension '' (filename is '', handling attachment: 0)
[b2e140]: HelperAppService::DoContent: mime 'application/octet-stream', extension ''
[b2e140]: Getting mimeinfo from type 'application/octet-stream' ext ''
[b2e140]: Extension lookup on '' found: 0x0
[b2e140]: Ext. lookup for '' found 0x0
[b2e140]: OS gave back 0x43609a0 - found: 0
[b2e140]: Searched extras (by type), rv 0x80004005
[b2e140]: MIME Info Summary: Type 'application/octet-stream', Primary Ext ''
[b2e140]: Type/Ext lookup found 0x43609a0
interesting files if you want to look at mozilla sources:
data uri handler: netwerk/protocol/data/nsDataHandler.cpp
where mozilla decides the filename: uriloader/exthandler/nsExternalHelperAppService.cpp
InternalLoad string in the log: docshell/base/nsDocShell.cpp
I think you can stop searching a solution for now, because I suspect there is none :)
as noticed in this thread html5 has download attribute, it works also on firefox 20 http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download
The following Javascript snippet works in Chrome by using the new 'download' attribute of links and simulating a click.
function downloadWithName(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
link.click();
}
And the following example shows it's use:
downloadWithName("data:,Hello%2C%20World!", "helloWorld.txt")
No.
The entire purpose is that it's a datastream, not a file. The data source should not have any knowledge of the user agent handling it as a file... and it doesn't.
you can add a download attribute to the anchor element.
sample:
<a download="abcd.cer"
href="data:application/stream;base64,MIIDhTC......">down</a>
Using service workers, this is finally possible in the truest sense.
Create a fake URL. For example /saveAs/myPrettyName.jpg
Use URL in <a href, <img src, window.open( url ), absolutely anything that can be done with a "real" URL.
Inside the worker, catch the fetch event, and respond with the correct data.
The browser will now suggest myPrettyName.jpg even if the user opens the file in a new tab, and tries to save it there. It will be exactly as if the file had come from the server.
// In the service worker
self.addEventListener( 'fetch', function(e)
{
if( e.request.url.startsWith( '/blobUri/' ) )
{
// Logic to select correct dataUri, and return it as a Response
e.respondWith( dataURLAsRequest );
}
});
Look at this link:
http://lists.w3.org/Archives/Public/uri/2010Feb/0069.html
Quote:
It even works (as in, doesn't cause a problem) with ;base64 at the end
like this (in Opera at least):
data:text/plain;charset=utf-8;headers=Content-Disposition%3A%20attachment%3B%20filename%3D%22with%20spaces.txt%22%0D%0AContent-Language%3A%20en;base64,4oiaDQo%3D
Also there is some info in the rest messages of the discussion.
There is a tiny workaround script on Google Code that worked for me:
http://code.google.com/p/download-data-uri/
It adds a form with the data in it, submits it and then removes the form again. Hacky, but it did the job for me. Requires jQuery.
This thread showed up in Google before the Google Code page and I thought it might be helpful to have the link in here, too.
Here is a jQuery version based off of Holf's version and works with Chrome and Firefox whereas his version seems to only work with Chrome. It's a little strange to add something to the body to do this but if someone has a better option I'm all for it.
var exportFileName = "export-" + filename;
$('<a></a>', {
"download": exportFileName,
"href": "data:," + JSON.stringify(exportData, null,5),
"id": "exportDataID"
}).appendTo("body")[0].click().remove();
This one works with Firefox 43.0 (older not tested):
dl.js:
function download() {
var msg="Hello world!";
var blob = new File([msg], "hello.bin", {"type": "application/octet-stream"});
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
window.location.href=a;
}
dl.html
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<title>Test</title>
<script type="text/javascript" src="dl.js"></script>
</head>
<body>
<button id="create" type="button" onclick="download();">Download</button>
</body>
</html>
If button is clicked it offered a file named hello.bin for download. Trick is to use File instead of Blob.
reference: https://developer.mozilla.org/de/docs/Web/API/File
(This answer has been made deprecated by newer technology, but will be kept here for historical interest.)
It's kind of hackish, but I've been in the same situation before. I was dynamically generating a text file in javascript and wanted to provide it for download by encoding it with the data-URI.
This is possible with minormajor user intervention. Generate a link right-click me and select "Save Link As..." and save as "example.txt". As I said, this is inelegant, but it works if you do not need a professional solution.
This could be made less painful by using flash to copy the name into the clipboard first. Of course if you let yourself use Flash or Java (now with less and less browser support I think?), you could probably find a another way to do this.
<a href=.. download=.. > works for left-click and right-click -> save link as..,
but <img src=.. download=.. > doesn't work for right-click -> save image as.. , "Download.jped" is suggested.
If you combine both:<a href=.. download=..><img src=..></a>
it works for left-click, right-click -> save link as.., right-click -> save image as..
You have to write the data-uri twice (href and src), so for large image files it is better to copy the uri with javascript.
tested with Chrome/Edge 88
var isIE = /*#cc_on!#*/false || !!document.documentMode; // At least IE6
var sessionId ='\n';
var token = '\n';
var caseId = CaseIDNumber + '\n';
var url = casewebUrl+'\n';
var uri = sessionId + token + caseId + url;//data in file
var fileName = "file.i4cvf";// any file name with any extension
if (isIE)
{
var fileData = ['\ufeff' + uri];
var blobObject = new Blob(fileData);
window.navigator.msSaveOrOpenBlob(blobObject, fileName);
}
else //chrome
{
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
fs.root.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
var fileData = ['\ufeff' + uri];
var blob = new Blob(fileData);
fileWriter.addEventListener("writeend", function () {
var fileUrl = fileEntry.toURL();
var link = document.createElement('a');
link.href = fileUrl;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}, false);
fileWriter.write(blob);
}, function () { });
}, function () { });
}, function () { });
}
You actually can achieve this, in Chrome and FireFox.
Try the following url, it will download the code that was used.
data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==

Categories