Obtaining a PDF file through JavaScript that works on all browsers without compatibility issues

While I am able to successfully download a PDF using AngularJS in Chrome, it seems to encounter issues with the latest versions of FireFox, Internet Explorer 11, and Edge. It appears that a shim is required for IE9, although the current one doesn't seem to be effective. I have tried setting the response type to blob and arraybuffer, but this hasn't made a difference.

This contradicts what is indicated on caniuse regarding Blob URLs. Has anyone managed to get this working in IE9 and above, as well as the recent versions of FF? If so, could you please point out where I may be going wrong?

$http({
    url: '/api/v1/download',
    method: 'GET',
    responseType: 'blob' // or 'arraybuffer'
}).then(function (response) {

    var url = URL.createObjectURL(response.data);

    anchor.href = downloadUrl;
    anchor.download = filename;
    anchor.target = '_blank';
    anchor.click();

    URL.revokeObjectURL(downloadUrl);            
    anchor = null;

}).catch(function (reason) {

    console.log('FAIL', reason);
});

UPDATE

The currently suggested solution works for IE10, 11, Edge, and FF, while also remaining compatible with Chrome. However, IE9 requires another polyfill/shim, and Safari does not support the download attribute. Hence, I have left TODO stubs in these cases.

An updated version of the solution has been provided below with additional information added in the comments:

    function performDownload(blob, filename) {

        if(isIE() == 9) {

            // TODO: polyfill/shim/other... change response type to?
        }
      
        else if (typeof window.navigator.msSaveBlob !== 'undefined') {

            window.navigator.msSaveBlob(blob, filename);
        }
       
        else {

            var URL = window.URL;
            var downloadUrl = URL.createObjectURL(blob);
            var anchor = document.createElement('a');

            if(angular.isDefined(anchor.download)) {

                anchor.href = downloadUrl;
                anchor.download = filename;
                anchor.target = '_blank';
                document.body.appendChild(anchor);
                anchor.click();

                $timeout(function () {
                    URL.revokeObjectURL(downloadUrl);
                    document.body.removeChild(anchor);
                    anchor = null;
                }, 100);
            }
            else {

                // TODO: Safari does not support the download anchor attribute...
            }
        }
    }

Answer №1

I have successfully implemented this code in both Internet Explorer 11 and Google Chrome:

function downloadFile(response, mimeType, fileName) {
    let fileBlob = new Blob([response.arrayBuffer()], { type: mimeType });
    if (typeof window.navigator.msSaveBlob !== 'undefined') {
        // Workaround for Internet Explorer
        window.navigator.msSaveBlob(fileBlob, fileName);
    } else {
        let URL = window.URL;
        let downloadUrl = URL.createObjectURL(fileBlob);
        if (fileName) {
            let anchor = document.createElement('a');
            if (typeof anchor.download === 'undefined') {
                window.location.href = downloadUrl;
            } else {
                anchor.href = downloadUrl;
                anchor.download = fileName;
                document.body.appendChild(anchor);
                anchor.click();
            }
        } else {
            window.location.href = downloadUrl;
        }
        // Clean up
        setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); 
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Node js Express js token authentication: unraveling the implementation complexities

After extensive research on authentication methods for nodejs and express js, I find myself at a crossroads. So far, the most helpful tutorial I've found on sessions is this one. I am working with the mean stack and my main goal is to provide users ...

Is it possible to refresh text in table without clearing icons?

Is there a way to maintain icons in table rows when editing text fields from a dialog? Currently, regardless of whether I use .html() or .text(), the icons disappear. I suspect that utilizing .content() may be a solution, but I'm unsure how to impleme ...

Navigate to a specific section in an Accordion with the help of jQuery

I currently have 2 pages: page1.html, which contains a series of links, and page2.html, where an Accordion is located. The Query: I'm wondering if it's feasible to link directly to a specific section within the Accordion. For instance, if I want ...

Is React.js susceptible to XSS attacks through href attributes?

When user-generated links in an href tag appear as: javascript:(() => {alert('MALICIOUS CODE running on your browser')})(); This code was injected via an input field on a page that neglects to verify if URLs begin with http / https. Subseque ...

Keep a collection of completed promises stored in the inventory

Good day, I'm facing a challenge in Parse Javascript where I am trying to save items after receiving them in a loop. However, outside the loop, the array of objects remains empty. .. define global ** var filesUpload = []** for (var key in files) { ...

Tips for adjusting the dimensions of material table within a react application

Could someone please provide guidance on adjusting the size of a table made with material table? I am currently working in React and the following code is not yielding the desired outcome. I even attempted to use 'react-virtualized-auto-sizer' wi ...

TypeScript creates a .d.ts file that contains declaration statements rather than export declarations

When compiling my code using the command tsc --p typescript/tsconfig.json --outFile "dist/umd/index.d.ts", I encountered an issue. The contents of my tsconfig.json file are as follows: { "include": ["../src/**/*"], "exclude": ["../**/*.test.ts"], ...

Issue encountered while attempting to synchronize the protractor with the webpage: "Unable to access property 'get' of undefined"

When I access my test target page, it has a Single Sign-On (SSO) integrated login system. After hitting the page, a SSO-integrated Windows authentication process takes place before redirecting to the home page. I attempted to disable Sync for the first te ...

Move on to the next iteration in the FOR loop in Node JS

Is there a way to skip item 3 in the loop without breaking it? for (var i = 1; i<= 9; i++) { if (i==3) break; console.log(i); } I had a tough time searching for an answer online because I am unsure of the exact terminology to use. Desired output: ...

Unable to display canvas background image upon webpage loading

Currently working on a JavaScript project to create a captcha display on a canvas. The issue I'm facing is that the background image does not load when the page initially opens. However, upon hitting the refresh button, it functions as intended. Here& ...

Exploring Three.js: How to Integrate and Utilize 3D Models

Hey there! I've been doing a lot of research online, but I can't seem to find a solution that works for me. My question is: How can I integrate 3D models like collada, stl, obj, and then manipulate them using commands like model.position.rotation ...

Handlers for adjustments not correctly updating values in introduced object

I am facing an issue with a table that displays data fetched from an API and a select dropdown. Whenever a checkbox is selected, the name key along with its value is added to an array object named selectedFields. checkbox = ({ name, isChecked }) => { ...

Acquiring data from an API response in JSON format using JavaScript

Utilizing a parse.com API server, I have successfully established communication in JavaScript through AJAX. The output from the response is being logged into the browser console with the following code: $.ajax(settings).done(function(response) { ...

Leveraging CSS or JavaScript for Displaying or Concealing Vacant Content Sections

I'm working on developing a page template that utilizes section headers and dynamically pulled content from a separate database. The current setup of the page resembles the following structure: <tr> <td> <h3> ...

What is the process for uploading an image with express-fileupload?

Looking to upload an image to Cloudinary via Postman using the express-fileupload library for handling multipart forms. Here is a snippet from my index.ts file: import fileUpload from "express-fileupload"; app.use(fileUpload()); In my controller ...

Is there a way to remove text from a div when the div width is reduced to 0?

Upon loading the page, my menu is initially set to a width of 0px. When an icon is clicked, a jQuery script smoothly animates the menu's width to fill the entire viewport, displaying all menu items (links) perfectly. The issue I'm facing is that ...

"Encountering difficulties in utilizing the Chrome message passing API through Selenium's execute_script function

Currently, I am trying to send a value to a chrome extension from a browser automation script by invoking the chrome.runtime.sendMessage API from Selenium. Below is the python code I am using: import os import time from selenium import webdriver from sele ...

Utilizing a JavaScript Library in your Scala.js Project: A Step-by-Step Guide

I am currently following a tutorial on setting up dependencies in my Scala.js project. Here is the link to the tutorial: First and foremost, I have organized my project setup as shown below: https://github.com/scala-js/scalajs-cross-compile-example Wi ...

Utilizing AngularJS 1.X to implement filters on transformed information

When using the combination of ng-repeat and a filter, it creates a highly effective search function. However, once the data is converted, the use of a filter for searching becomes limited. For Instance JavaScript $scope.ints = [0,1,2,4,5,6,7,8,9, ..., 9 ...

Exploring the implications of Content Security Policy in conjunction with mod_pagespeed evaluations

I am currently in the process of configuring CPS rules for my website. One issue I have encountered is that mod_pagespeeds often uses 'unsafe-eval' for scripts, which goes against my security settings. An example of code generated by mod_pagespee ...