This code works in all major browsers excpet in latest Opera 71 (Windows).
The behaviour is that no error or info shows up but the download never starts from end user perspective. In developer tools I see the binary content of the example pdf document in response tab.
It seems that the dynamic creation of tags is not working.
function downloadFile(urlToSend) {
var req = new XMLHttpRequest();
req.open("GET", urlToSend, true);
req.responseType = "blob";
req.onload = function (event) {
var URL = window.URL || window.webkitURL;
var contentType = req.getResponseHeader('content-type');
var blob = new Blob([req.response], {type: contentType});
var downloadUrl = URL.createObjectURL(blob);
var contentDisposition = req.getResponseHeader('content-disposition');
//var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
var filename = 'doku.pdf'; //contentDisposition.match(/filename*="(.+)"/)[1];
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location.href = downloadUrl;
} else {
//code which gets executed by Opera
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location.href = downloadUrl;
}
};
req.send();
}
I am able to get the pdf in the new window with URL as
htts://mydomainname/410-8d9c-4883-86c5-d76c50a24a1d
I want to remove the auto generated blob name (410-8d9c-4883-86c5-d76c50a24a1d) in the generated URL and place my custom name link below
htts://mydomainname/filename
What modifications i need to do for below code
var file = new Blob([response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
$window.open(fileURL);
Not sure exactly where this code lives for you, but here is a solution using XmlHttpRequest "onload".
oReq.onload = function(e) {
if (this.status === 200) {
const blob = new Blob([oReq.response], { type: "image/pdf"})
let a = document.createElement("a");
a.style = "display: none";
document.body.appendChild(a);
let url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'myFile.pdf'; // gives it a name via an a tag
a.click();
window.URL.revokeObjectURL(url);
} else {
// handler error eee
}
}
Basically rather than $window.open(fileURL); you need to programmatically create a anchor tag, setting its href with the window.URL.createObjectURL as youve done above.
Hope this helps,
Matt
Is it possible to use an ajax call to open FileStreamResult as a downloaded file?
Controller method
public FileStreamResult DownloadPDF()
{
var stream = myHandler.getFileStream("myfile.pdf");
return File(stream, "application/pdf", "myfile.pdf"));
}
Html code
Click Me
<script type="text/javascript>
$("a.mydownload").click(function () {
$.ajax({
method: 'GET',
url: 'http://myserver/file/DownloadPDF',
success: function (data, status, jqXHR) {
var blob = new Blob([data], { type: "application/pdf" })
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
document.body.appendChild(a);
a.href = url;
a.click();
}
});
});
</script>
Running on IE I get access denied, but on Chrome it runs fine. I do however get a "blank"/invalid pdf.
Use XMLHttpRequest() with responseType set to "blob", add download attribute to <a> element
$("a.mydownload").click(function () {
var request = new XMLHttpRequest();
request.responseType = "blob";
request.open("GET", "http://myserver/file/DownloadPDF");
request.onload = function() {
var url = window.URL.createObjectURL(this.response);
var a = document.createElement("a");
document.body.appendChild(a);
a.href = url;
a.download = this.response.name || "download-" + $.now()
a.click();
}
request.send();
});
alternatively, you can use jquery-ajax-blob-arraybuffer.js. See also Add support for HTML5 XHR v2 with responseType set to 'arraybuffer' on $.ajax
Still had issues with IE11, but a minor change to #guest271314 solutions, seems to do the trick.
Set responseType after open.
Use msSaveBlob on IE
$("a.mydownload").click(function() {
var request = new XMLHttpRequest();
request.open("GET", "http://myserver/file/DownloadPDF");
request.responseType = "blob";
request.onload = function() {
var msie = window.navigator.userAgent.indexOf("MSIE");
if (msie > 0) {
window.navigator.msSaveBlob(this.response, "myfile.pdf");
} else {
var url = window.URL.createObjectURL(this.response);
var a = document.createElement("a");
document.body.appendChild(a);
a.href = url;
a.download = this.response.name || "download-" + $.now()
a.click();
}
}
request.send();
});
I'm using an HTML5 site to create a log per-say within a textarea element. I need to pull the data from that area with the click of a button, and download it to my computer via a .txt file. How would I go about doing this if it is possible??
HTML:
<input type="button" onclick="newBlob()" value="Clear and Export">
Javascript:
function newBlob() {
var blobData = document.getElementById("ticketlog").value;
var myBlob = new Blob(blobData, "plain/text");
blobURL = URL.createObjectURL(myBlob);
var href = document.createElement("a");
href.href = blobURL;
href.download = myBlob;
href.id = "download"
document.getElementById("download").click();
}
I figure if I make the Blob, create a URL for it, map the URL to an "a" element then auto-click it then it should work in theory. Obviously I'm missing something though. Any help would be fantastic. 1st question on this site btw:p
The simplest way I've come up with is as follows:
function download(text, filename){
var blob = new Blob([text], {type: "text/plain"});
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
}
download("this is the file", "text.txt");
List of possible blob filestypes: http://www.freeformatter.com/mime-types-list.html
const downloadBlobAsFile = (function closure_shell() {
const a = document.createElement("a");
return function downloadBlobAsFile(blob, filename) {
const object_URL = URL.createObjectURL(blob);
a.href = object_URL;
a.download = filename;
a.click();
URL.revokeObjectURL(object_URL);
};
})();
document.getElementById("theButton").addEventListener("click", _ => {
downloadBlobAsFile(new Blob(
[document.getElementById("ticketlog").value],
{type: "text/plain"}
), "result.txt");
});
The value of a download property of an <a> element is the name of the file to download, and the constructor of Blob is Blob(array, options).
I used this approach that doesn't involve creating an element and revokes the textFile after the browser showed the text file
var text = 'hello blob';
var blob = new Blob([text], { type: 'text/plain' });
let textFile = window.URL.createObjectURL(blob);
let window2 = window.open(textFile, 'log.' + new Date() + '.txt');
window2.onload = e => window.URL.revokeObjectURL(textFile);
How do you set the name of a blob file in JavaScript when force downloading it through window.location?
function newFile(data) {
var json = JSON.stringify(data);
var blob = new Blob([json], {type: "octet/stream"});
var url = window.URL.createObjectURL(blob);
window.location.assign(url);
}
Running the above code downloads a file instantly without a page refresh that looks like:
bfefe410-8d9c-4883-86c5-d76c50a24a1d
I want to set the filename as my-download.json instead.
The only way I'm aware of is the trick used by FileSaver.js:
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.
Here is a simplified example (jsfiddle):
var saveData = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, fileName) {
var json = JSON.stringify(data),
blob = new Blob([json], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
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);
I wrote this example just to illustrate the idea, in production code use FileSaver.js instead.
Notes
Older browsers don't support the "download" attribute, since it's part of HTML5.
Some file formats are considered insecure by the browser and the download fails. Saving JSON files with txt extension works for me.
I just wanted to expand on the accepted answer with support for Internet Explorer (most modern versions, anyways), and to tidy up the code using jQuery:
$(document).ready(function() {
saveFile("Example.txt", "data:attachment/text", "Hello, world.");
});
function saveFile (name, type, data) {
if (data !== null && navigator.msSaveBlob)
return navigator.msSaveBlob(new Blob([data], { type: type }), name);
var a = $("<a style='display: none;'/>");
var url = window.URL.createObjectURL(new Blob([data], {type: type}));
a.attr("href", url);
a.attr("download", name);
$("body").append(a);
a[0].click();
window.URL.revokeObjectURL(url);
a.remove();
}
Here is an example Fiddle. Godspeed.
Same principle as the solutions above. But I had issues with Firefox 52.0 (32 bit) where large files (>40 MBytes) are truncated at random positions. Re-scheduling the call of revokeObjectUrl() fixes this issue.
function saveFile(blob, filename) {
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
const a = document.createElement('a');
document.body.appendChild(a);
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 0)
}
}
jsfiddle example
Late, but since I had the same problem I add my solution:
function newFile(data, fileName) {
var json = JSON.stringify(data);
//IE11 support
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
let blob = new Blob([json], {type: "application/json"});
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {// other browsers
let file = new File([json], fileName, {type: "application/json"});
let exportUrl = URL.createObjectURL(file);
window.location.assign(exportUrl);
URL.revokeObjectURL(exportUrl);
}
}
This is my solution. From my point of view, you can not bypass the <a>.
function export2json() {
const data = {
a: '111',
b: '222',
c: '333'
};
const a = document.createElement("a");
a.href = URL.createObjectURL(
new Blob([JSON.stringify(data, null, 2)], {
type: "application/json"
})
);
a.setAttribute("download", "data.json");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
<button onclick="export2json()">Export data to json file</button>
saveFileOnUserDevice = function(file){ // content: blob, name: string
if(navigator.msSaveBlob){ // For ie and Edge
return navigator.msSaveBlob(file.content, file.name);
}
else{
let link = document.createElement('a');
link.href = window.URL.createObjectURL(file.content);
link.download = file.name;
document.body.appendChild(link);
link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
link.remove();
window.URL.revokeObjectURL(link.href);
}
}
Working example of a download button, to save a cat photo from an url as "cat.jpg":
HTML:
<button onclick="downloadUrl('https://i.imgur.com/AD3MbBi.jpg', 'cat.jpg')">Download</button>
JavaScript:
function downloadUrl(url, filename) {
let xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function(e) {
if (this.status == 200) {
const blob = this.response;
const a = document.createElement("a");
document.body.appendChild(a);
const blobUrl = window.URL.createObjectURL(blob);
a.href = blobUrl;
a.download = filename;
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(blobUrl);
document.body.removeChild(a);
}, 0);
}
};
xhr.send();
}
window.location.assign did not work for me. it downloads fine but downloads without an extension for a CSV file on Windows platform. The following worked for me.
var blob = new Blob([csvString], { type: 'text/csv' });
//window.location.assign(window.URL.createObjectURL(blob));
var link = window.document.createElement('a');
link.href = window.URL.createObjectURL(blob);
// Construct filename dynamically and set to link.download
link.download = link.href.split('/').pop() + '.' + extension;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
this is a good easy solution for it.
function downloadBloob(blob,FileName) {
var link = document.createElement("a"); // Or maybe get it from the current document
link.href = blob;
link.download = FileName;
link.click();
}