How to serve an image from Express.js to React - javascript

I am trying to serve up an image from my public directory on my node.js + express backend to the client side which is Reacts (create-react-app to be particular).
I have the typical file structure of
-public
-images
-image.jpeg
On my client side, I have an image tag with a relative path like so
<img src='/images/me.jpeg' alt="" />
My app.js for express looks like so
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const app = express();
const contactRouter = require('./routes/contact');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(__dirname + "/public"));
app.use(express.static(path.join(__dirname, 'client/build')));
//route handlers
app.use('/contact', contactRouter);
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/client/build/index.html'));
});
module.exports = app;
alas, I am not getting any luck with the image being served up. Any ideas for this? I am not sure if I also need an additional proxy for when I am in dev. I have tried this which likes in my src folder in react
const proxy = require('http-proxy-middleware');
module.exports = function (app) {
app.use(proxy('/images/*', { target: 'http://localhost:5000' }));
}
I appreciate the help guys!

Related

Failed to load module script: expected a javascript module script but server responded with a MIME type of text/jsx

Ive created an express server and created an api and also ive installed react through vite for my frontend. when I try to connect or load my main html file to the server the console gives that error. Im new to express
Here's My express app code
const express = require("express");
const dotenv = require("dotenv");
const errorMiddleware = require("./middleware/error");
const cookieParser = require("cookie-parser");
const fileupload = require("express-fileupload");
const app = express();
const bodyParser = require("body-parser");
const cors = require("cors");
const path = require("path");
//config for env file
dotenv.config({ path: `${__dirname}/config/config.env` });
app.use(cors());
app.use(express.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ limit: "50mb" }));
app.use(cookieParser());
app.use(fileupload());
// Route Imports
const productRoutes = require("./routes/productRoutes");
const userRoutes = require("./routes/userRoutes");
const orderRoutes = require("./routes/orderRoute");
const paymentRoute = require("./routes/paymentRoute");
//using all routes
app.use("/api/v1", productRoutes);
app.use("/api/v1/user", userRoutes);
app.use("/api/v1", orderRoutes);
app.use("/api/v1", paymentRoute);
app.use(express.static(path.join(__dirname, "../frontend")));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "../frontend/index.html"));
});
//error HAndler Middleware
app.use(errorMiddleware);
module.exports = app;
You can't serve your JSX files, you need to first build your front-end, so npm run build and then serve the content of your build folder ( in my case it's dist/ )
app.use(express.static(path.join(__dirname, "./front/dist/")));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "./front/dist/index.html"));
})

Heroku url routes can only be reached programmatically

Sorry if this question is vague but I really don't know what code to present.
I have a Heroku webpage which is running fine. I am using reach-router to navigate from one page to another on button clicks: <button onClick={() => navigate('/intro')}>Click</button>. When I do this the url changes appropriately and my content is visible. However if I type in the exact same url I get an error saying Cannot GET /intro. This error even happens if I use the button click to navigate and then reload the page.
It's my understanding that app.use(express.static('build')); will serve my static files.
So why can I visit pages if I start at my root url and navigate from there but I can't enter a url and travel to that page?
The website is live here https://build-a-wedding.herokuapp.com/
Adding more details on my server.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
const sessionMiddleware = require('./modules/session-middleware');
require('dotenv').config();
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(sessionMiddleware);
app.use(cors());
// Serve static files
app.use(express.static('build'));
app.use(express.static(path.resolve(__dirname, '..', 'build')));
const users = require('./routes/users.router');
const dataFetch = require('./routes/data.router');
const venues = require('./routes/venues.router');
app.use('/users', users);
app.use('/location', dataFetch);
// app.use('/', auth);
app.use('/venues', venues);
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`Listening on port: ${PORT}`);
});
When I navigate programmatically here is what i see for my sources
When I type in the same URL here is the source tree
Just create a static.json file at the root of your React project with the following content:
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
This question is possibly duplicated
Make sure that your express app are listening to these routes and sending response to them.
Example:
app.get('/intro', function (req, res) {
res.send(pathToPage);
});

MIME type ('text/html') is not a supported

Here are some lines of code... I have another application running that is setup exactly the same and I am having no issues.
app.use('/app', express.static(__dirname + "/public"));
Here is the link tag
<link rel="stylesheet" type="text/css" href="/app/css/app.css">
It does the same with this img tag
<img src="/app/img/SCS-NewLogo_donl.svg" height="65px" width="350px" id="sc-logo">
I am not sure why, but it seems to be sending the file as HTML. Usually this means the file is not found on the server, but I checked myself and confirmed that it is.
Full file
const express = require('express');
const config = require('./lib/config');
const bodyParser = require('body-parser');
const URLS = require('./lib/URLS.js');
const PORT = process.env.PORT || 9005;
const ENV = config.ENV || 'TEST';
const SERVER = config.SERVER;
const app = express();
app.set('views', './views');
app.set('view engine', 'ejs');
app.use('/app', express.static(__dirname + "/public"));
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.all(/^\/apps$/, function (req, res) {
res.redirect('/apps/job-search');
});
app.get('/apps/job-search', (req, res) => {
res.render('pages/search');
});
app.post('/apps/job-search/send-input', (req, res) => {
// Send data to API server which will handle DB query...
axios.get(URLS.GatherSearchResults)
.then(resp => {
console.log(resp.data);
}).catch(err => {
console.log(err)
});
});
app.listen(PORT, () => {
console.log('App is listening on port ' + PORT + ' on server ' + SERVER + '...');
});
Directory Structure
Root
public
css
img
views
pages
search.ejs
partials
header.ejs
footer.ejs
app.js
I thinkk I see your issue. After declaring the route /app as static, you remap it to '/apps/job-search' several lines later.
Change the static line to app.use('/', express.static(__dirname + "/public")); and your links in the HTML file should start wit /css and /img etc.
Verify that by trying to open one of your existing links, and seeing what content you're currently serving (my guess - it'd be whatever is at '/apps/job-search').

using files with express server

var express = require('express'),
app = express(),
db = require('./db'),
bodyParser = require('body-parser'),
controller = require('./controller');
app.use(express.static('../public'));
app.get('/server', function (req, res) {
console.log(__dirname);
res.sendFile('/../client/index.html');
});
I have this express server set up but using the code above I get "Cannot GET /" when I view localhost:portnumber. If I change the GET method to:
app.get('/', function(req, res) {
res.sendFile(__dirname + '../client/index.html');
});
I get "'C:\Users\TC\Documents\Desktop\myapp\multiplayerWebSite\server..\client\index.html' at Error (native)" and if I change it to:
app.get('/', function(req, res) {
res.sendFile('../client/index.html');
});
I get "TypeError: path must be absolute or specify root to res.sendFile"
Error: ENOENT: no such file or directory
The server was working perfectly when I had everything in the root directory, but I wanted to change the folder structure to make it more neat/professional. If anyone could tell me what I'm doing wrong I'd appreciate it greatly. Thank you in advance!
You can use path module, there is a join method that take multiple paths to make one.
Exemple if you do:
path.join('test/musicfolder', '../videofolder/allreadyseen')
you will get 'test/videofolder/allreadyseen' .
you can see all the doc here : https://nodejs.org/api/path.html
var express = require('express'),
path = require('path'),
app = express(),
db = require('./db'),
bodyParser = require('body-parser'),
controller = require('./controller');
app.use(express.static(path.join(__dirname, '../public')));
app.get('/server', function (req, res) {
console.log(__dirname);
res.sendFile(path.join(__dirname, '../client/index.html'));
});

Blocking static file access in expressJS

I'm trying to block certain files in my site from being publicly accessible. For example, if you go to mysite.com/package.json instead of displaying it in the browser i just want to send and error or redirect back to my homepage or something. I feel like this should be easy... but i haven't been able to get anything to work. there isn't anything complicated about the site, and it's running of a fairly simple server.js
var appRoot = __dirname,
express = require('express'),
chalk = require('chalk'),
mongoose = require('mongoose'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
path = require('path'),
errorhandler = require('errorhandler'),
os = require('os'),
http = require('http'),
Routes;
// -----------------------------
// Configuration
// -----------------------------
var port, env, logs;
// Switch some vars based on the ENV
if(process.env.NODE_ENV === 'production'){
port = 3000;
env = 'production';
} else {
port = 8080;
env = 'development';
}
// Express Variables
var app = express();
var router = express.Router();
// Use static files in root
app.use(express.static(__dirname));
// API config
app.use(bodyParser.json());
app.use(methodOverride());
app.use(errorhandler({ dumpExceptions: true, showStack: true }));
// Database
mongoose.connect(mydb);
// Routes / API Config
Routes = require(appRoot + '/routes')(app, router, mongoose);
// After all routes don't match ie. refreshing a page, send index.html
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/index-' + env + '.html');
});
app.listen(port);
I was hoping to do something like:
app.get('/package.json', function(){
res.end('Not allowed');
});
or even before i send it the static html index check if they are trying to access a restricted file. Any suggestions, resources etc are welcomed. If you need any more info just ask.
Based on your comment
You should replace this line:
app.use(express.static(__dirname ));
with this:
app.use('/assets', express.static(__dirname + '/assets'));
app.use('/views', express.static(__dirname + '/views'));

Categories