2017-01-05 56 views
4

我可以在Chrome中使用AngularJS下載PDF,但這似乎不適用於最新的FireFox,Internet Explorer 11或Edge(假設它不適用於IE10或者),我知道一個shim is needed for IE9。不知道這是否是最好的選擇,如果任何人有意見,但目前似乎並不奏效。我嘗試了blobarraybuffer的響應類型,以防萬一發生變化,但它不會。使用跨瀏覽器兼容的JavaScript下載PDF

這一切都反映了caniuse指出的關於使用Blob網址的內容。任何人都可以在IE9以及FF的最後幾個版本中工作,並可以指出我做錯了什麼?

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

    // Use the Blob object to create an object URL to download the file 
    var url = URL.createObjectURL(response.data); 
    // var url = URL.createObjectURL(new Blob([response], {type: 'application/pdf'})); // arraybuffer version 

    // Create an anchor to perform download, but don't append to the DOM 
    anchor.href = downloadUrl; 
    anchor.download = filename; 
    anchor.target = '_blank'; 
    anchor.click(); 

    URL.revokeObjectURL(downloadUrl);    
    anchor = null; 

}).catch(function (reason) { 

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

UPDATE

目前最好的(唯一的)答案適用於IE10,11,邊緣,FF,並繼續使用Chrome工作。如果任何人有另一個polyfill/shim/other/etc,IE9將無法使用此解決方案,並且Safari不支持下載屬性,因此所選答案中的解決方案在SPA中不起作用,因爲它只是重定向當前頁面所以在這兩種情況下,我都離開了TODO存根。

這是一個更新與添加註釋,任何人使用或希望添加更多的信息張貼的答案,從而有望IE9和Safari工作:

function performDownload(blob, filename) { 

     // IE9 has no API for handling downloads using Blob objects, and doesn't support the download attribute 
     if(isIE() == 9) { 

      // TODO: polyfill/shim/other... change response type to? 
     } 
     // Only works for IE10 and up, including Edge 
     else if (typeof window.navigator.msSaveBlob !== 'undefined') { 

      // Provides a prompt to save the file to a location of users choice 
      window.navigator.msSaveBlob(blob, filename); 
     } 
     // Browsers that adhere to current standards can implement downloads 
     // using the Blob object with the download anchor attribute 
     // --- 
     // NOTE: Edge 13+ is compliant with both these standards, but Edge 12 
     // does not support the download anchor attribute so all versions 
     // have been grouped to use the propriety `msSaveBlob` method 
     else { 

      // Use the Blob object to create an object URL to download the file 
      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); // Required by Firefox 
       anchor.click(); 

       // Release the existing object URL, and the anchor 
       $timeout(function() { 
        URL.revokeObjectURL(downloadUrl); 
        document.body.removeChild(anchor); 
        anchor = null; 
       }, 100); 
      } 
      else { 

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

謝謝@ guest271314我發現下面的答案滿足我需要關於瀏覽器兼容性的問題,因爲我可以在Chrome中下載文件,並且所有重複問題表示是我已經擁有的只能在Chrome中使用的代碼。我的問題不是如何下載,而是如何在不同的瀏覽器下載它。事實證明,Firefox需要將錨定在DOM中,因此需要使用不同於Chrome的附加功能; IE10,11和Edge需要'msSaveBlob'。另外,根據caniuse,另一個鏈接中的「application/octet-stream」在Safari中有已知的問題。 – mtpultz

回答

4

我已經在這兩個成功使用該IE11和Chrome:

function saveBlob(response, contentType, filename) { 
    let blob = new Blob([response.arrayBuffer()], { type: contentType }); 
    if (typeof window.navigator.msSaveBlob !== 'undefined') { 
     // IE workaround 
     window.navigator.msSaveBlob(blob, filename); 
    } else { 
     let URL = window.URL; 
     let downloadUrl = URL.createObjectURL(blob); 
     if (filename) { 
      let a = document.createElement('a'); 
      if (typeof a.download === 'undefined') { 
       window.location.href = downloadUrl; 
      } else { 
       a.href = downloadUrl; 
       a.download = filename; 
       document.body.appendChild(a); 
       a.click(); 
      } 
     } else { 
      window.location.href = downloadUrl; 
     } 
     // cleanup 
     setTimeout(function() { URL.revokeObjectURL(downloadUrl); }, 100); 
    } 
} 
+0

謝謝,這很好。 IE10,11,Edge,FF和Chrome。需要在Safari中測試它,IE9需要Blob和'msSaveBlob'的墊片。即使我爲'msSaveBlob'找到一個polyfill,甚至不知道如何測試IE9。 – mtpultz

+1

如果你想測試老版本的IE,微軟爲此做了一些工具 https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ –

+0

非常感謝@AndrewDiamond我最終購買了一個幾個月的https://www.browserstack.com,因爲它允許我在Yosemite +的iOS 7上的Windows 7,8,8.1,10和Safari 8+上測試IE9 +,Chrome和Firefox多年,以及在不同設備上的每一個移動版本。 – mtpultz