How to download a file from server in react? - node.js

I have a Node.js backend that sends an icon image to a React frontend. Initially, I encode this image as a Base64 string and store it directly in the database. I created an api that returns this string to the frontend. However, I read that it is bad to store it in the database, so I re-wrote the api to store this string in the server as a json file and now my api returns the absolute path to this json file. However, how is the React frontend supposed to retrieve the file? Is it possible to use the absolute path or do I have to create another api to return a file object ? If so, how do I do that?
I'm a newbie at both react and node.js so any help is appreciated.Thanks.
EDIT: I stored the file path as __dirname of where my code resides + filename.I'm getting cors error when accessing that url

Use Express to share out that folder as such-and-such.
Suppose you keep your files in a folder called files, just off the root. And suppose your server structure looks roughly like this:
- backend
- app.js
- frontend
- Components
- Routes
- public
- dev
- index.html (your template file)
- files
- myimage.png
In your root js file (app.js? server.js? index.js?):
const app = express()
app.use('/static', express.static('public'));
app.use('/files', express.static('public/files'));
Then, in the frontend code:
<img src='/files/myimage.png' />
By the way, there is no problem storing images as base64 in your database... but every database backup will also backup those images. If you have a small database, no worries. However, if you have a LOT of images, especially very large images, this will make your database (and backups) unnecessarily large and unwieldy.
Everything depends on your use case.

Related

Is it more efficient for severs to send an image file or a path to an image file to the client?

I'm using express js to serve files to an angular app and I'm deciding between these approaches:
res.status(201).json({ imagepath: '<URL>' });
res.sendFile('<URL>');
I'm thinking that sending the url will force an extra round trip so I should go with the sendFile but I want to doublecheck. Is there anything I'm missing?
The best option would be to store the image file on something like AWS S3 and then send the file URL using your Express application. You would use the aws-sdk package here to save the image to S3 (detailed article here). Then you would send the URL location of that image to your database to be stored.

Relative path of static files express/react

I'm running my react client on localhost:3000 and my express server on localhost:4000, and I have a static folder in my server with images.
I'm trying to save the image path to a MySQL database, and use that in React as an img src, but can't figure out how to do it without hard coding the path. For example, localhost:4000/images/img1.jpg works, but if I change the host name tomorrow, all of my db data becomes irrelevant.
Three answers:
In react you can fill props by joining a constant string and a variable. Just save the /images/img1.jpg in the database instead of full URL. Then in react do <img src={'http://localhost:4000/' + imagePathFromDB} />. When you change the server just change it once.
You can create a simple SQL query to update your DB to be relevant this is the beauty of SQL database.
For e.g.
update images set path=replace(path,'localhost:4000','newdomain.com')
Voilla!
If you using create-react-app you can serve the frontend and backend from the same domain using the proxy parameter. And then just save in the database /myimage.jpg and in React <img src={myVariable} />

Get image from localhost to localhost with express and nodejs

I´m building an app with NodeJs and Angular
The server runs on http://localhost:9000
And the app runs on http://localhost:4200
I have an endpoint whose looks like this http://localhost:9000/users
I use this to retrive all users
The set returned has a key like this { photo: myphoto.jpg }
When I loop the set of data, I want to render the image as this way
<img src="{{ url }}/uploads/users/{{ user.photo }}" alt="{{ user.name }} {{ user.last_name }}"
class="img-fluid shadow-sm avatar100 ml-auto mr-auto d-block rounded-circle">
Where url is http://localhost:9000 and user.photo is myphoto.jpg
The complete route is http://localhost:9000/uploads/users/myfoto.jpg
There is the photo hosted, but the server is throwing an error
Cannot GET /uploads/users/myfoto.jpg
I think, the server is interpreting the URL as API route, and obviously is not declared on routes file.
I want to only retrive the image, how could I do that?
I don´t know what part of my code I can show here. Routes? Front-end? Project structure? Tell me what do you need
With Express, you have to create a route that will handle your image URLs. By default, Express (or the built-in node.js web server) does not serve ANY files. So, it will only serve a file if you create a handler for that specific URL and program that handler to deliver the desired file.
If your images are directly in the file system where the URL base filename matches the actual filename in your server file system, you could use express.static() to create a single route that would serve all your images.
For example, you could use express.static like this:
app.use("/uploads/users", express.static("/uploads/users"));
This would allow a URL requested from:
http://localhost:9000/uploads/users/myphoto.jpg
to be automatically served from the server-side file system at
/uploads/users/myphoto.jpg
It would similarly work for any other matching name in that same directory (or even sub-directories of that directory if the sub-directory was also in the URL).
In general, you don't want to surface internal path names such as /uploads/users all the way back to the user's HTML pages. So, you could do this instead in the HTML page:
<img src="/images/myphoto.jpg">
And, this on the server:
app.use("/images", express.static("/uploads/users"));
This will take any http requests that start with a path of /images and look for the matching filename in /uploads/users on the server, thus not exposing the internals of your server directory structure to the client. It creates the notion of an abstract /images URL that your server can then process and get the images from wherever they happen to be stored on the server.
$ npm i multer
and server add
app.use("/public", express.static("public")); //The folder where the file is located

Not able to access images from upload folder - express - multer - react

I am working on my first ever MERN stack web app. I finished development and trying to host in VPS.
Everything working fine. But, I am not able to view the uploaded images. I share you the few details about the project structure.
React app is build for production and kept in public folder.
Upload folder is created where user uploaded images are kept and its location is stored in DB. (ex: /uploads/user1/img1.jpg). Using Multer to handle image upload.
This is the folder structure of my Express server which also servers static files.
-MAIN_EXPRESS_APP_FOLDER
------Routes
------Public
------Uploads
------package.json
To make public and upload static, following codes are added in Server.js file:
app.use(express.static(path.join(__dirname,'/public')));
app.get('/*',(req,res)=>{
res.sendfile(path.join(__dirname='public/index.html'));
})
app.use('/uploads', express.static('uploads'))
I am able to access my web app and also i can insert data in DB. Image upload is working as expected. But, Express not serving uploaded images.
What could be problem?
As for static content you set the folder to be public now what i think is you should move your uploads folder inside public and try to access the images hope they will be served currently your application is not allowing to server data else then public directory hope it will help you

How do I prevent Node.js / Express serving up my application's source code?

I never thought this would be a problem with Node.js and Express, but on a crazy whim I decided to type into a browser the location of one of the source files in my Node.js Express project - something like:
http://www.mywebsite.com/mynodejsapp/app.js
To my extreme horror, my application's source code popped right up, publicly available for all to see.
So, that aside: how do I stop it in Node.js / Express?
My setup code is pretty straightforward:
var app = express();
app.configure(function() {
app.use(express.static('/home/prod/server/app/public'));
});
app.listen(8888);
To clarify, this is what my folder structure looks like:
/home/prod/server/
/home/prod/server/app.js
/home/prod/server/public/
All sorts of various files that are intended for public access live under /public. All of my server source code lives under /server/, and my understanding of Express's static folder configuration is that the static folder is the only place that Express happily serves up files from the filesystem from.
Any ideas?
From what you posted it really smells like the URL you entered is served by e.g. Apache/nginx/... and you did put your node app within the document root. The answer is simple in this (and any similar) case:
You never put any of your sourcecode files within the document root or another HTTP-accessible folder. In your case, /home/prod/server/app/public should contain only client-side stuff (HTML, CSS, Graphics, (minified) client-side JS) and nginx should not have anything above this folder as its document root.

Resources