简体   繁体   中英

Serving PDFs in React

I currently have a front end React app on my localhost at port 8080 and a backend Express server on port 9000 (I think these have to be different ports but I may be wrong). My goal is to have links on my webpage that will download PDFs (or other files like Excel sheets) to a user's local machine but I am unsure how to go about this.

If I have the PDFs on the Express server side I thought of 2 options

  1. Create a static folder in Express which holds all the file
const app = express();
app.use('/static', express.static(path.join(__dirname, 'MyPDFs')));

and then user anchor tags in my React app to point to the files I need

<a href="http://localhost:9000/static/myFile.pdf">Link to PDF </a>
  1. Setup routes in Express and send response downloads
var express = require("express");
var router = express.Router();

/* GET home page. */
router.get("/static", function (req, res, next) {
  res.download("MyPDFs/myFile.pdf");
});

and then make Http requests from React using fetch or the axios package like I found from this link

axios({
  url: 'http://localhost:9000/static',
  method: 'GET',
  responseType: 'blob',
}).then((response) => {
  const url = window.URL.createObjectURL(new Blob([response.data]));
  const link = document.createElement('a');
  link.href = url;
  link.setAttribute('download', 'file.pdf');
  document.body.appendChild(link);
  link.click();
});

But this solution doesn't seem very clean as I have read that browsers do not natively support downloading files from requests and I need 3rd party packages to do this.

The whole other entire option is to place these files in a directory on the front end React app but I would prefer not to do that. I would prefer to keep these PDFs (or other files like Excel) on the server side and somehow retrieve these files from React. I don't necessarily need these files to be downloaded when a user clicks a link (although thats preferable), but at least to have it display in the browser.

What is the "best practice / standard" approach for this situation? Do PDF files go on the server side or client? Should I simply link to the files on the other port or send Http requests, or something else? Thank you in advance.

https://blog.logrocket.com/programmatic-file-downloads-in-the-browser-9a5186298d5c/ this may be of use to you.

HTML5 introduced the download property to tags.

Although not every browser will support it, you'll find you may never run into a user with an outdated browser (check the compatibility first of course).

My way would be to upload the file to a storage provider and have the content downloaded from there,/CDN using an approach similar to the link. I'd use my front-end to send the file to my API, ensure it's validated/authenticated before uploading it into my storage mechanism.

However, this introduces complexity and cost, so I'm not sure if it'd be suitable for your application. I certainly couldn't say if it's a standard or not.

That also doesn't really answer your question, I'd stick to your current approach and not worry too much about the best way until your current way isn't good enough.

Also just mount your static file folder so it can be served instead of handling the route.

https://expressjs.com/en/starter/static-files.html

After re-reading your question, you could say this would be a combination of both approaches, downloading from the front-end, without storing your files in React.

Finally, you don't need to make a fetch or axios request, you just need to know the location of the file, the browser will handle the downloading through the HTML5 tag, eliminating the additional network calls

TL;DR:

  1. Use Express with a staticly mounted directory
  2. Upload files from React to Express, placing in your static directory
  3. Use React to link the location with a download property in the Html tag
  4. Download

When you deal with scale, I'd recommend an optional step 5:

  1. Use Express to upload content to a static storage mechanism that can be served using a CDN.

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