【问题标题】:Dowload PDF as a stream of bytes将 PDF 下载为字节流
【发布时间】:2018-01-22 04:46:37
【问题描述】:

我有 Web API,可将文件存储为字节流。响应已被提取并保存在状态中,但现在我想从我的反应应用程序 onClick 按钮下载文件。我这样做如下:

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

调试后正确获取流,但下载文件会产生错误: 加载 PDF 文档时出错。

更新:

使用此源调用新端点:

  callLoadContract: {
    remote( state, id, contractId ) {
      const url = `${base}/vendor/${id}/${contractId }`;
      return $http.instance.api.get( url, id, contractId);
    },
    success: Actions.contractLoaded,
    error: Actions.fail
  }

处理响应:

  loadContract({id, contractId}) {
    this.getInstance().callLoadContract( id, contractId );
  }

  contractLoaded( response ) {
    if (response && response.data) {
      console.log(response);
      const file = new Blob([response.data], { type: 'application/pdf' });
      const fileURL = URL.createObjectURL(file);
      window.open(fileURL);
    }
  }

同样的错误。

【问题讨论】:

  • 哪种响应类型正在接收您的 JS 代码,arraybuffer 还是 blob?
  • 你为什么不从后端/api/download?fileId=XXXX 提供它?
  • 我获取的 JSON 对象有几个文档。它们是 blob 形式,我在一个 GET 中获取它们,然后用户应该选择查看哪一个。 @CarlosDelgado
  • @dinchev 多个文件在同一个实体中
  • @user1912404,您所说的在概念上是错误的,JSON 字符串中的 blob :v ?您能否详细解释一下您的问题以及是否有可能的服务器端代码?

标签: javascript reactjs pdf reactjs-flux


【解决方案1】:

也许您的问题与在客户端处理 PDF 的方式无关,因为您的代码运行良好:

import React from 'react';

export default class App extends React.Component {
    constructor(props, context) {
        super(props, context);
    }

    downloadContract() {
        var oReq = new XMLHttpRequest();

        var URLToPDF = "https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf";

        oReq.open("GET", URLToPDF, true);

        oReq.responseType = "blob";

        oReq.onload = function() {
            // Once the file is downloaded, open a new window with the PDF
            // Remember to allow the POP-UPS in your browser
            const file = new Blob([oReq.response], { type: 'application/pdf' });

            const fileURL = URL.createObjectURL(file);

            window.open(fileURL, "_blank");
        };

        oReq.send();
    }

    render() {
        return (
            <div>
                <input type="button" onClick={this.downloadContract} value="Download PDF File"/>
            </div>
        );
    }
}

正如预期的那样,当用户单击“下载”时,PDF 将被下载并显示在浏览器的新窗口中。

然而,最简单的方法是@dinchev 提到的,只需将它放在一个 URL 中就可以了。

【讨论】:

  • 我同意你的观点,我们应该调用一个单独的端点来获取文档。只有一个问题,我可以用通量架构实现相同的想法吗?
  • 它工作但没有通过 altjs。我会接受的。
  • 对我有用,但我不想路由到新页面,只需下载
【解决方案2】:

这是我下载文件但不路由到新页面的解决方案:

try {
            let httpClient = new XMLHttpRequest();
            let pdfLink = "http://localhost/";
            httpClient.open('get', pdfLink, true);
            httpClient.responseType = "blob";
            httpClient.onload = function() {
                const file = new Blob([httpClient.response], { type: 'application/pdf' });
                const fileURL = URL.createObjectURL(file);
                const link = document.createElement("a");
                link.href = fileURL;
                link.download = "fileName.pdf";
                link.click();
                // document.body.removeChild(link);
                URL.revokeObjectURL(fileURL);
            };
            httpClient.send();
        } catch (e) {
            console.log(e);
        }

【讨论】:

    猜你喜欢
    • 2020-12-24
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多