Blob下载在IE中不起作用

时间:2013-12-01 09:25:59

标签: javascript internet-explorer angularjs blob compatibility

我在我的Angular.js控制器中有下载CSV文件:

 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();

这适用于Chrome,但不适用于IE。浏览器控制台日志说:

  

HTML7007:通过关闭blob来撤消一个或多个blob URL   他们被创造了。这些网址将不再作为数据解析   支持URL已被释放。

这是什么意思,我该如何解决?

11 个答案:

答案 0 :(得分:66)

请尝试使用thisuseragent

if (navigator.appVersion.toString().indexOf('.NET') > 0)
        window.navigator.msSaveBlob(blob, filename);
else
{
 var blob = new Blob(['stringhere'], { 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();
}

答案 1 :(得分:32)

IE不允许您直接打开blob。您必须使用msSaveOrOpenBlob。还有msSaveBlob

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

答案 2 :(得分:15)

我需要使用Blob来下载转换后的base64 PNG图像。我能够使用window.navigator.msSaveBlob

在IE11上成功下载blob

请参阅以下msdn链接: http://msdn.microsoft.com/en-us/library/hh779016(v=vs.85).aspx

具体来说,您应该致电:

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

其中blobObject是以通常方式创建的Blob。

答案 3 :(得分:3)

Chrome,Internet Explorer Firefox和Opera的完整解决方案

此页面上有很多不错的地方,但是我不得不结合使用一些方法来使所有功能正常工作。希望对您有帮助。

  1. 使用按钮或链接来触发名为download()的功能:
<button class="button-no save-btn" ng-click="download()">DOWNLOAD</button>
  1. 将其放在您的控制器中:
$scope.download = function () {

    // example shows 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) {

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

    } else {

        // 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 to the DOM (Firefox)
        downloadLink.attr('style','display:none');
        angular.element(document.body).append(downloadLink);

        // trigger click
        downloadLink[0].click();
    }
};

答案 4 :(得分:1)

您的IE浏览器版本是什么?您需要一个现代浏览器或IE10 + http://caniuse.com/bloburls

答案 5 :(得分:1)

也许你需要一些延迟。怎么样:

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

答案 6 :(得分:1)

我需要让下载功能在Chrome和IE11中运行。我用这段代码取得了很大的成功。

HTML

#include <opencv2/highgui.hpp>
#include <vector>

template <typename T, typename ... Ts>
void insert_all(std::vector<T> &vec, Ts ... ts)
 {   
     (vec.push_back(ts), ...);
 }


void rgb_mats(cv::Mat& results)
{
    std::vector<cv::Mat> bgr;
    bgr.reserve(3);

    cv::Mat B(100,100, CV_8UC1, cv::Scalar(255,0,0));
    cv::Mat G(100,100, CV_8UC1, cv::Scalar(0,255,0));
    cv::Mat R(100,100, CV_8UC1, cv::Scalar(0,0,255));

    insert_all(bgr, B,G, R);

    cv::merge(bgr, results);
}

int main ()
{
cv::Mat rgb_results;
rgb_mats(rgb_results);
}

JS

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

答案 7 :(得分:0)

尝试使用此代替: var blob = file.slice(0,file.size);

答案 8 :(得分:0)

这样做,对我来说很好。

downloadFile(data) {
    if (navigator.msSaveBlob) {
      let blob = new Blob([data], {
        "type": "text/csv;charset=utf8;"
      });
      navigator.msSaveBlob(blob, this.fileName);
    }
    else {
      let blob = new Blob(['\ufeff' + data], { type: 'text/csv;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.fileName);
      $link.style.visibility = "hidden";
      document.body.appendChild($link);
      $link.click();
      document.body.removeChild($link);
    }
  }

答案 9 :(得分:0)

如下所示创建polyfill方法,由于我的下载文件名是静态的,因此具有可变的文件名。在不支持blob函数的情况下(如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);
            });
        }
    });
}

答案 10 :(得分:0)

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));
    }

获取文件名。使用以下功能。

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;
  }

这对我有用。