简体   繁体   中英

Pass PDF as Blob from Azure to Node to React

I am attempting to grab a PDF stored in Azure Blob Storage via a node backend and then serve that PDF file to a React Frontend. I am using Microsofts @azure/storage-blob with a BlockBlobClient but every example I find online converts the readableStreamBody to a string. The blob has a content type of application/pdf . Ive tried passing the readableStreamBody and the pure output to the frontend but those result in broken pdf's. I also followed the documentation online and made it a string and passed that to the frontend. That produced a PDF that would open and had the proper amount of pages but was completly blank.

Node.js Code on the Backend

   app.get('/api/file/:company/:file', (req, res) => {
  const containerClient = blobServiceClient.getContainerClient(req.params.company);
  const blockBlobClient = containerClient.getBlockBlobClient(req.params.file);
  blockBlobClient.download(0)
    .then(blob => streamToString(blob.readableStreamBody))
    .then(response => res.send(response))
});

FrontEnd Code

getFileBlob = (company,file) => {
    axios(`/api/file/${company}/${file}`, { method: 'GET', responseType: 'blob'})
      .then(response => {
        const file = new Blob(
          [response.data],
          {type: 'application/pdf'});
        const fileURL = URL.createObjectURL(file);
        window.open(fileURL);
      })
      .catch(error => {
        console.log(error);
      });
  }

This might help you, its working for me.

Node

var express = require('express');
const { BlobServiceClient } = require('@azure/storage-blob');

var router = express.Router();


const AZURE_STORAGE_CONNECTION_STRING = 
'YOUR_STRING';
async function connectAzure() {

// Create the BlobServiceClient object which will be used to create a container         client
const blobServiceClient = BlobServiceClient.fromConnectionString(
  AZURE_STORAGE_CONNECTION_STRING
);

const containerName = 'filestorage';
  const blobName = 'sample.pdf';
  console.log('\nConnecting container...');
  console.log('\t', containerName);

  // Get a reference to a container
  const containerClient = blobServiceClient.getContainerClient(containerName);

  // Get a block blob client
  const blockBlobClient = containerClient.getBlockBlobClient(blobName);
  for await (const blob of containerClient.listBlobsFlat()) {
    console.log('\t', blob.name);
  }

  const downloadBlockBlobResponse = await blockBlobClient.download(0); 
    const data = await streamToString(downloadBlockBlobResponse.readableStreamBody)
    return data;

    }

async function streamToString(readableStream) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    readableStream.on('data', data => {
      chunks.push(data.toString());
    });
    readableStream.on('end', () => {
      resolve(chunks.join(''));
    });
    readableStream.on('error', reject);
  });
}

  router.get('/', async function(req, res, next) {
    const data = await connectAzure();
    res.send({data}).status(200);
  });


module.exports = router;

Front-end

function createFile() {
fetch('/createfile').then(res => {
    res.json().then(data => {
        var blob = new Blob([data.data], { type: 'application/pdf' });
        var fileURL = URL.createObjectURL(blob);
        if (filename) {
            if (typeof a.download === 'undefined') {
                window.location.href = fileURL;
            } else {
                window.open(fileURL, '_blank');
            }
        }
    })
}).catch(err => console.log(err))
}

HTML

<body><h1>Express</h1><p>Welcome to Express</p><button    onclick="createFile()">Create File</button></body>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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