简体   繁体   English

显示 pdf 文件并从 arraybuffer blob 下载 onclick

[英]Displaying pdf files and dowloading onclick from an arraybuffer blob

I am creating pdf in nodejs backend and storing them in my DB as blobs.我正在 nodejs 后端创建 pdf 并将它们作为 blob 存储在我的数据库中。

In my frontend(React), I am calling the api and receiving whole list of blobs data and converting it into files as below.在我的前端(React)中,我正在调用 api 并接收完整的 blob 数据列表并将其转换为如下文件。 Then creating URLs from them and storing URLs as array and in state.然后从它们创建 URL 并将 URL 存储为数组和状态。

componentDidMount() {
    const fileURLs = [];
    fetch(`/api/invoices`)
      .then((res) => res.json())
      .then((invoices) => {
        this.setState({ invoices });
        invoices.map((inv) => {
          const file = new Blob([inv.file_content], {
            type: "application/pdf",
          });
          const fileURL = URL.createObjectURL(file);
          fileURLs.push(fileURL);
        });
        this.setState({ fileURLs });
      })
  }

Also the blob data I am receiving looks like this: blob data我收到的 blob 数据也如下所示: blob 数据

Inside my render(), I linked the url to anchor tag to open it in new tab.在我的 render() 中,我将 url 链接到锚标记以在新选项卡中打开它。 Urls looks like this: blob:http://localhost:3000/1b5c4fe3-bb7c-4850-8804-d850f824b07f网址如下所示: blob:http://localhost:3000/1b5c4fe3-bb7c-4850-8804-d850f824b07f

this.state.invoices.map((p, i) => (
...
  <a
    href={this.state.fileURLs[i]}
    target="_blank"
    rel="noopener noreferrer"
  >
    {p.file_name}
  </a>
...
)

If I visit the url it just says Failed to load PDF document.如果我访问该网址,它只会显示无法加载 PDF 文档。

In my backend I am storing response.arrayBuffer() as my blob data.在我的后端,我将response.arrayBuffer()存储为我的 blob 数据。 I am also saving pdf in local file system just to test and it creates the pdf files without any problem.我还在本地文件系统中保存 pdf 只是为了测试,它可以毫无问题地创建 pdf 文件。

Edit: I am attaching some of my backend code as well.编辑:我还附上了我的一些后端代码。

.then(async data => {
  const response = await fetch(api, {
      method: "GET",
      headers: {
          "Accept": "application/octet-stream",
          "Authorization": "Bearer " + token
      },
      encoding: null
 });
const filename = response.headers.get('Content-Disposition')
    .split(';')
    .find(n => n.includes('filename='))
    .replace('filename=', '')
    .trim();
const invoice = await response.arrayBuffer();
return [filename, invoice];
})
.then(data => {
    const created = moment().format('YYYY-MM-DD HH:mm:ss');
    //save pdf file in local directory
    var base64Str = Buffer.from(data[1]).toString('base64');
    base64.base64Decode(base64Str, './frontend/src/invoices/' + data[0]);
    
// save pdf in database table
    const query = `call create_invoice_procedure('${data[0]}','${data[1]}','${created}')`;
    connection.query(query, (err, rows) => {
        if (err) {
            throw err;
        }
     });
  })

Invoices route to get all invoices:获取所有发票的发票路径:

router.get('/', (req, res) => {
    var query = `SELECT * from table`;
    connection.query(query, (error, results) => {
        if (error) {
            return error;
        }
        else {
            res.json(results);
        }
    })
});

So the problem for me is I am not able to view or download the pdf in frontend.所以对我来说问题是我无法在前端查看或下载 pdf。

If you're sure that your blob is correct, try adding a click event on any element to open url instead of using href on anchor tag.如果您确定您的 blob 是正确的,请尝试在任何元素上添加单击事件以打开 url,而不是在锚标记上使用 href。 This works for me:这对我有用:

const blob = new Blob([fileData], {
        type: 'application/pdf'
      });
      const fileURL = URL.createObjectURL(blob);
      window.open(fileURL, '_blank', 'location=yes,height=650,width=1000,scrollbars=yes,status=yes');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM