I am trying to download a PDF file (which requires a Bearer token, so I cannot just open a new tab with the given URL) and then open it in a new tab. I've gotten this to work in every browser except Firefox. In Firefox, the tab opens, but upon trying to navigate to the blob URL, the tab closes. If I copy and paste the blob URL into a new tab manually, it loads the PDF correctly.
Below is the code I am using (the dollar signs are from Angular 1):
showReceipt: function(receiptUrl) {
var windowReference;
if (!($window.navigator && $window.navigator.msSaveOrOpenBlob)) {
// This is the workaround for Safari: https://stackoverflow.com/a/39387533/2595915
// It also works in Chrome, but not in IE and Edge
// We open the new window in an if block to avoid opening a useless blank tab in IE/Edge
windowReference = $window.open();
}
api.request('GET', receiptUrl, {}, {}, { useUrl: true, successHandler: api.blobSuccessHandler, responseType: 'blob' }).then(
function (blob) {
// It is necessary to create a new blob object with mime-type explicitly set
// otherwise only Chrome works like it should
var newBlob = new Blob([blob], { type: 'application/pdf' });
// IE and Edge don't allow using a blob object directly as link href;
// instead it is necessary to use msSaveOrOpenBlob
if ($window.navigator && $window.navigator.msSaveOrOpenBlob) {
$window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
var data = $window.URL.createObjectURL(newBlob);
windowReference.location.href = data; // Causes the tab to close
console.log(data); // Copy and pasting this URL works, assuming I comment out the revoke command below
$timeout(function () {
$window.URL.revokeObjectURL(data);
}, 100);
}
);
}
I have also tried programmatically creating a temporary a
element and clicking that, and I get the same results (tab immediately closes in Firefox, works fine in Chrome).