I'm downloading a dynamically generated PDF from a 3rd party API and displaying it to the end user. This works great, using URL.createObjectURL()
, with the sole exception that I can't set the title of the file (or window) when presenting it in a new window. This question from 2013 has essentially the same problem, but no solutions to this particular issue. I've tried editing newWindow.document.title
both before and after assigning the object URL as the new location with no luck. My guess is that this is simply impossible, but I thought I'd ask anyway.
Note: I have no control over the PDF or the API generating it. I also don't have the option of inserting a local server between this app and the API, which would be my preferred solution (so I could call the API and set the Content-Disposition
headers). I'm setting the location
of a new window with a URL that looks like blob:http://localhost:3000/1e1e526d-ff4d-4797-9e5d-b4327813a747
. Saving this file yields a dialog box with a pre-filled filename like 1e1e526d-ff4d-4797-9e5d-b4327813a747
. The question is whether it's possible to change that filename.
Here's the code used to fetch the file and display it in a new window, for reference (this is an Angular app):
let isMSIEorEdge = window.navigator && window.navigator.msSaveOrOpenBlob;
// Create the URL
let url = <API_URL>;
// Create the JSON data to send
let data = {
... API-specific data ...
};
// Set up basic headers
let headers = new Headers();
headers.append('Content-Type', 'application/json');
// For non-MS browsers, open a new window to show the document in
// This must be done here because it's still part of the user-initiated
// action (mouse click)
let newWin;
if (!isMSIEorEdge) {
newWin = window.open('', 'pdfWindow');
}
// Call the method and subscribe to the result
this.http
.post(url, data, {
headers,
responseType: ResponseContentType.Blob
})
.subscribe(
res => {
// Get the filename from the response headers
let filename = res.headers
.get('content-disposition')
.match(/filename=(.*)$/)[1];
// Create a File object from the data
let file = new File([res.blob()], filename, {
type: 'application/pdf'
});
// For IE/Edge, trigger Save/Open dialog
if (isMSIEorEdge) {
window.navigator.msSaveOrOpenBlob(file, filename);
return false;
}
// For all other browsers, open in new window
let href = window.URL.createObjectURL(file);
newWin.location.assign(href);
newWin.name = newWin.document.title = filename;
// Clear the object URL to avoid memory leaks
setTimeout(() => {
window.URL.revokeObjectURL(href);
}, 100);
},
err => {
// Handle any HTTP errors
console.log(err);
throw err;
}
);
}