Issue with downloading files in Internet Explorer is not functioning properly

I am encountering an issue in my Angular.js controller where downloading a CSV file works perfectly in Chrome but not in IE. The browser console log indicates:

HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed.

The code snippet causing this problem is as follows:

 var blob = new Blob([csvContent.join('')], { type: 'text/csv;charset=utf-8'});
 var link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
 link.href = URL.createObjectURL(blob);
 link.download = 'teams.csv';
 link.click();

Can someone please help me understand what this error means and provide guidance on how to fix it?

Answer №1

Use either this or useragent for this task.

if (navigator.appVersion.toString().indexOf('.NET') > 0)
        window.navigator.msSaveBlob(blob, filename);
else
{
 var blob = new Blob(['content'], { type: 'text/csv;charset=utf-8' });
 var link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
 link.href = URL.createObjectURL(blob);
 link.download = 'data.csv';
 link.click();
}

Answer №2

Internet Explorer does not support opening blobs directly. You must utilize msSaveOrOpenBlob instead. Another option is to use msSaveBlob

if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
    var objectUrl = URL.createObjectURL(blob);
    window.open(objectUrl);
}

Answer №3

When I needed to download a base64 PNG image after converting it, I found success by using a Blob. The process went smoothly on IE11 thanks to window.navigator.msSaveBlob

If you want more detailed information, check out the MSDN link provided below: http://msdn.microsoft.com/en-us/library/hh779016(v=vs.85).aspx

To make it work, simply use the following code:

window.navigator.msSaveBlob(blobObject, 'msSaveBlob_testFile.txt');

In this snippet, remember that blobObject should be created in the usual manner as a Blob object.

Answer №4

Comprehensive Solution for Chrome, Internet Explorer Firefox and Opera

This page contains various useful elements, but I had to combine different methods to make them all function properly. I hope this guide assists you.

  1. Add a button or link that calls the download() function:
<button class="button-no save-btn" ng-click="download()">DOWNLOAD</button>
  1. Insert the following code in your controller:
$scope.download = function () {

    // Example demonstrates using a JSON file
    var content = JSON.stringify($scope.stuffToPutInFile, null, "  ");
    var blob = new Blob([content], {type: 'application/json;charset=utf-8'});

    if (window.navigator && window.navigator.msSaveBlob) {

        // Workaround for Internet Explorer
        $log.warn("Triggering download using msSaveBlob");
        window.navigator.msSaveBlob(blob, "export.json");

    } else {
        
        // For other browsers
        $log.warn("Triggering download using webkit");
        var url = (window.URL || window.webkitURL).createObjectURL(blob);
        
        // Create invisible element
        var downloadLink = angular.element('<a></a>');
        downloadLink.attr('href', url);
        downloadLink.attr('download', 'export.json');
        
        // Make link invisible and add it to the DOM (Firefox)
        downloadLink.attr('style','display:none');
        angular.element(document.body).append(downloadLink);
        
        // Trigger click
        downloadLink[0].click();
    }
};

Answer №5

Which version of Internet Explorer are you using? Ensure that you have a current browser or IE10+ http://caniuse.com/bloburls

Answer №6

If you're looking to add a delay, consider using the following snippet:

button.addEventListener('click', function(){
    setTimeout(function(){
        document.body.createElementNS('http://www.w3.org/1999/xhtml', 'a');
        URL.revokeObjectURL(link.href);  
    }, 100);
});

Answer №7

After encountering issues with the download feature not working in Chrome and IE11, I was able to find a solution that worked effectively.

HTML

<div ng-repeat="attachment in attachments">
  <a ng-click="openAttachment(attachment)" ng-href="{{attachment.fileRef}}">{{attachment.filename}}</a>
</div>

JS

$scope.openAttachment = function (attachment) {
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(
      b64toBlob(attachment.attachment, attachment.mimeType),
      attachment.filename
    );
  }
};

Answer №8

This method has been effective for me and is working perfectly.

fetchDocument(content) {
    if (navigator.msSaveBlob) {
      let blob = new Blob([content], {
        "type": "text/csv;charset=utf8;"
      });
      navigator.msSaveBlob(blob, this.docName);
    }
    else {
      let blob = new Blob(['\ufeff' + content], { type: 'text/plain;charset=utf-8;' });
      let $link = document.createElement("a");
      let url = URL.createObjectURL(blob);
      $link.setAttribute("target", "_blank");
      $link.setAttribute("href", url);
      $link.setAttribute("download", this.docName);
      $link.style.visibility = "hidden";
      document.body.appendChild($link);
      $link.click();
      document.body.removeChild($link);
    }
  }

Answer №9

Consider utilizing the following code snippet: var chunk = file.slice(0, file.size);

Answer №10

To address the issue of blob function not being supported in certain cases, a polyfill method can be created. In this method, a variable named `filename` is used to handle static download filenames. This workaround will come in handy when dealing with browsers like Internet Explorer.

if (!HTMLCanvasElement.prototype.toBlob) {
    Object.defineProperty(HTMLCanvasElement.prototype, 
        'toBlob', {
            value: function (callback, type, quality) {
                var canvas = this;
                setTimeout(function () {
                    var binStr = atob(canvas.toDataURL(type, quality).split(',')[1]),
                        len = binStr.length,
                        arr = new Uint8Array(len);

                    for (var i = 0; i < len; i++) {
                        arr[i] = binStr.charCodeAt(i);
                    }

                    var blob = new Blob([arr], {
                        type: 'image/png'
                    });

                    window.navigator.msSaveOrOpenBlob(blob, fileName);
                });
            }
        });
}

Answer №11

try {
      const blob = new Blob([res.body], {
        type: res.headers.get('Content-Type'),
      });
      const file = new File([blob], this.getFileName(res), {
        type: res.headers.get('Content-Type'),
      });

      saveAs(file);
    } catch (err) {
      var textFileAsBlob = new Blob([res.body], {
        type: res.headers.get('Content-Type'),
      });
      window.navigator.msSaveBlob(textFileAsBlob, this.getFileName(res));
    }

To retrieve the filename from a response, you can utilize the following function.

getFileName(response: any) {
    let name: string;
    try {
      const contentDisposition: string = response.headers.get(
        'content-disposition'
      );
      const [, filename] = contentDisposition.split('filename=');
      name = filename;
    } catch (e) {
      name = 'File_Name_Not_Specified_' + new Date();
    }
    return name;
  }

This method has proven effective in my use case.

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

Browser Shuts Down Due to Angular ng-pattern

Our application uses a specific regular expression for email validation, and unfortunately, switching it out may not be an option at this point. However, we have discovered that certain steps cause the JavaScript in the browser to crash. This issue has bee ...

Detecting the scroll events of elements with the overflow:hidden property

Looking to synchronize scrolling between two different panels or divs? In one element, there's an overflow: auto while the other has overflow: hidden (trying to mimic a grid with frozen columns). I've managed to sync the scroll when it occurs w ...

Issue with updating JSON data

After implementing the following code in my AngularJS table to remove a row: $scope.removeRow = function (index) { if (index === -1) { alert("Something has gone wrong"); } else { $scope.budgetdetails.splice(index, 1); } I have noticed that my JSON data a ...

Having trouble getting smooth scrolling with easing to function properly

I'm facing an issue with a JQuery function that is supposed to enable smooth scrolling using JQuery easing, but for some reason, it's not functioning correctly and I'm unable to pinpoint the error. Here is the code for the function: $(func ...

What is the best way to use form input to filter an Observable?

Within my component, I have declared the variable "countries$": countries$!: Observable<Country[]>; To populate this variable with data from this API, I use the following code in the "ngOnInit" lifecycle hook: ngOnInit(){ this.countries$ ...

No AngularJs HTTP resource could be located on the WebAPI

Currently, I am working on an Angular application that utilizes WebAPI. Whenever I make a call to any method, I encounter the error message "HTTP resource not found" within Angular. This is the Angular call: service.Login = function (email, password, call ...

Error loading code. Works when manually pasted, but not when executed with JavaScript

After some trial and error, I found that this code works perfectly if I manually copy the content from the class isotope in 1.php to the class grid on this page. However, when I try to use JS to do the same thing, it mysteriously stops working. Any sugge ...

Doesn't the use of asynchronous programming in Node.js lead to a potential StackOverflow issue?

Recently, I identified an issue with the Node.js (single-threaded) platform: As requests are handled by the server and they undergo processing until being blocked due to I/O operations. Once a request is blocked for processing, the server switches ba ...

Exploring the properties of a file directory

As I try to access the d attribute of a path that was generated using Javascript, the output of printing the path element appears as follows: path class=​"coastline" d="M641.2565741281438,207.45837080935186L640.7046722156485,207.0278378856494L640.698 ...

Converting EDN data to a string and back in Clojure/ClojureScript

When working with JavaScript, one can convert a JavaScript data structure into a JSON string using the following code: JSON.stringify({somedata: { somesubdata: {}}}) Then, to parse it back into a JS data structure, you can use: var my_obj = JSON.parse(" ...

The session variable fails to update across several requests

I am looking to track the number of requests sent by a browser and store it in the session. Below is the code snippet I have written: import express from 'express'; import expressSession from 'express-session'; import path from "pa ...

Attempting to generate a nested array structure in order to produce a JSON object for output

I am currently working on a JavaScript script that interacts with the Netsuite ERP platform to retrieve data. Currently, the script is returning data in an array format, specifically product information. While this is functional, I would prefer it to retu ...

What steps can be taken to ensure the random generator continues to function multiple times?

My little generator can choose a random item from an array and show it as text in a div. However, it seems to only work once. I'm looking for a way to make it refresh the text every time you click on it. var items = Array(523,3452,334,31,5346); var r ...

Customized link routing / Deep linking

I need some help. I am managing a standard website and I want to redirect custom URLs to specific pages when visitors access the site. For instance: - index.html should point to custom_index.cfm?custom_id=1&page_id=1&inc=index - about.html shou ...

Repetition of UTM Parameters

I created a web page with a donation form embedded in it. Donors visiting the page come through a link that includes a source code at the end. I managed to include this source code in the URL of the embedded form using the following code: $(document).ready ...

Error encountered in Node.js: The listener must be a function

I've been working on adapting the solution provided in (How to create a simple http proxy in node.js?) from HTTP to HTTPS. However, upon attempting to access the proxy through my browser, the server abruptly stops and throws the following error: eve ...

Issue with Chart.js V3.20: Struggling to Filter Legend Labels

Building a dynamic line chart using Chart.js with the capability of up to 19 datasets. The issue arises when there are less than 19 datasets, as the legend still displays for these unused datasets. Previously, a function was used in Chart.js 2.6.0 options ...

Is it possible to modify this code to accept multiple IDs at once?

I'm attempting to create a form in JavaScript where, upon entering the necessary details and clicking submit, the user's email client opens with the information pre-filled for easy sending. However, I am facing challenges as my code involves mult ...

It is not possible to include external JavaScript in a Vue.js web page

Trying to integrate a Google Translate widget onto my webpage has been a bit challenging. Initially, when I added it to a normal webpage, it worked smoothly using the following code: <div class="google_translate" id="google_translate_element"></d ...

Creating an AngularJS directive specifically for a certain <div> tag

Recently, I began learning angularjs and came across a script to change the font size. However, this script ended up changing all <p> tags on the entire webpage. Is there a way to modify the font size of <p> tags only within the <div class=" ...