【问题标题】:Download a by ByteArray as pdf /handle error in React在 React 中将 ByteArray 下载为 pdf /handle 错误
【发布时间】:2019-08-29 11:55:14
【问题描述】:

我有一个从 react 调用的 api。它返回一个pdf文件。当我单击链接作为href时,我可以下载pdf。 现在,我调用的是一个函数,而不是一个href,单击并从该函数中调用api。但我无法下载该文件。 这就是我正在做的:

 fetch(<url>, {
        method: "GET",
        headers: {
            Accept: "application/pdf",
            "Content-Type": "application/pdf",
        },

    }).then(response => response.blob())
        .then(response => {
            var blob=response
            var reader = new window.FileReader();
            reader.readAsDataURL(blob);
            reader.onloadend = function() {
            var base64data = reader.result;
            window.open(base64data);
            }
        })
        .catch(error => {
            console.error(error);
        });

我无法下载任何文件。 api(用 kotlin 编写)返回一个字节数组。 此外,如果 api 抛出异常而不是返回 bytearray,我需要显示一个弹出窗口, 对此有什么想法吗?

【问题讨论】:

    标签: reactjs fetch


    【解决方案1】:

    要下载文件,您可以使用file-saver npm 包并按如下方式使用:

    import { saveAs } from 'file-saver';
    
    const file = new Blob([blob]);
    
    saveAs(file, 'fileName');
    

    在浏览器中打开文件:

    const file = new Blob([blob], {
      type: 'application/pdf',
    });
    
    const fileURL = URL.createObjectURL(file);
    
    window.open(fileURL);
    

    【讨论】:

    • 我已经用下载说明更新了我的答案。
    • 还有一个问题,如果我右键单击我的链接(以前是href,但现在它指向一个函数,可以下载pdf),我怎样才能获得下载pdf的选项?
    • 在回调中添加一个参数有条件的下载,否则在浏览器中打开?如(伪代码)const doSomething = (download) =&gt; fetch(....download ? saveFile : window.open...)
    • if (response != undefined){ const file = new Blob([response], { type: 'application/pdf', });另存为(文件,“文件名”); - 我现在有这个,我如何配置右键单击检查?困惑:(
    【解决方案2】:

    您可以在组件的某处创建一个不可见的锚标记并使用它。在我的解决方案中,我创建了一个不可见的锚标记,ID 为 invisible-link

    async function download(payload) {
        const response = await axios({
            url: getFileLink(payload), responseType: 'blob'
          })
        if (response.status !== 200) {
          // handle error
          return
        }
        const anchor = document.getElementById('invisible-link')
        const objectUrl = window.URL.createObjectURL(response.data)
        anchor.href = objectUrl;
        anchor.download = getDownloadFilename(response.headers)
        anchor.click()
        window.URL.revokeObjectURL(objectUrl)
    }
    
    function getDownloadFilename(headers = {}) {
      const { 'content-disposition' : disposition = '' } = headers
      const keyValue = disposition.split(';').find(e => e.includes('filename')) || ''
      const [,filename] = keyValue.split('=')
      return filename
    }
    

    这是我使用这种方法的代码的link

    【讨论】:

    • 非常感谢 - 对于任何碰巧没有名为“invisible-link”的 id 元素的人,您可以将该行替换为 document.createElement('a')
    猜你喜欢
    • 2012-04-05
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 2017-12-22
    相关资源
    最近更新 更多