ExpressJs static files not working correctly - javascript

I have an express app and the static files are not working for every route.
When I get to '/', the static styles and images work perfectly when index.ejs is rendered.
When I get '/efbhew', a route that doesn't exist, 404.ejs renders ok.
When I get '/asdw/feff' or other routes like '/df/fg/dfgdfg/sfgd', the static styles and images do not work. Is there something else I have to do in order for it to work?
Below is my code.
const app = express();
app.use(express.static(path.join(__dirname, '../public')));
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'ejs');
app.use(cors());
app.use(express.json());
app.get('/', async (req, res) => {
const posts = await Post.find({}).limit(7).sort({ createdAt: -1 }).exec();
res.render('index.ejs', {
latestPosts: posts
});
});
app.get('*', (req, res) => {
res.render('404.ejs');
});
This is the structure of my folders:
I tried changing the path of the public folders to go deeper since when I got to '/asdf/wfds/sdfsd', the image source is 'http://localhost:3000/asdf/wfds/img/logo.png' and it cant find it. But that still didn't work.

When an ejs page at /df/fg/dfgdfg/sfgd references a static file, as in
<img src="img/logo.png"/>
the URL is relative to the URL of the ejs page, so in this example it would be /df/fg/dfgdfg/img/logo.png (note the last segment sfgd is dropped, that's why it works for a page at /efbhew).
But the image exists only as /img/logo.png. Therefore, you should always address it with a path that starts with a slash, as in
<img src="/img/logo.png"/>

Related

Express Renders Pug File to Same URL?

When I fill out my form and submit my data, it renders my order.pug file on the browser, but my URL is still showing just localhost:3000 instead of localhost:3000/order?
My pug file is in a views folder and my express.js file is just on the main directory for my project
Here is my express file
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static(__dirname + "/public"));
app.set("view engine", "pug");
app.get("/orderPug", (req, res) => {
res.render("orderPug");
});
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "index.html"));
});
Then my post request to accept my data, then render my order.pug file
app.post("/create", async (req, res) => {
//API Authentication code is here
res.render("order")
});
My Pug File looks like this, so if I just navigate to localhost:3000/order it will show the value hard coded like below.
h1 Total: $#{totalCost}
But after I submit my form data it ends up looking like this, except the URL is still on localhost:3000
Total: $100.00
So when I submit my form, it shows the page has updated to order.pug yet the URL still just shows localhost:3000 and I don't think that makes sense for a confirmation page to show?

Serving css with express js

I have been having a lot of trouble with serving css using express js. I finally figured out how, but I'm a bit confused why my new code works, but my old code doesn't. This is my new code that does work:
const express = require('express');
const path = require('path');
const app = express();
const port = process.env.PORT || 5010;
console.log(__dirname)
app.use('/public', express.static('public'));
app.set('views', path.join(__dirname, 'views'))
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'views', 'home.html'));
});
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
My file system looks like this:
index.js
public
css
home.css
views
home.html
Originally instead of having:
app.use('/public', express.static('public'));
I had:
app.use(express.static(path.join(__dirname, 'public')));
Why does the second version work, but the first one doesn't? What is the purpose of the first parameter in the second version? Also, just in case it makes a difference, I'm coding on replit.com.
When using 1 parameter
app.use(express.static(path.join(__dirname, 'public')));
This code serve files in the "public" subdirectory of the current directory. The URL to access the file at public/css/home.css is : http://localhost/css/home.css
When using 2 parameters
app.use('/public', express.static('public'));
This code also serve files in the "public" subdirectory of the current directory, with a virtual path prefix "/public". So, the URL to access the file at public/css/home.css is : http://localhost/public/css/home.css
We can change the first parameter to anything, for example, if we have :
app.use('/static', express.static('public'));
Then the URL to the same file becomes : http://localhost/static/css/home.css.
You can find more information from the official document here

Why is html page sent by express.js route not connected to a css stylesheet?

So I have server.js file that imports a router
const path = require("path");
const express = require("express");
const app = express();
const PORT = 8080;
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(require('./app/routing/htmlRoutes'));
The router looks like this
const path = require("path");
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.sendFile('home.html', { root: path.join(__dirname, '../public') });
});
router.get('/survey', function(req, res) {
res.sendFile('survey.html', { root: path.join(__dirname, '../public') });
});
module.exports = router;
It does work! It renders html pages, however those html pages have css stylesheets hooked up to them and located in the same directory, but they render as blank html sheets (unstyled)...
How do I make them render with css stylesheets taken into account?
When the browser encounters the style reference of the loaded html file, it tries to load the file specified in the src attribute. Now your server script doesn't have a route for that. It will load the css if you add a route for that specific css file. However as Irshad said, the standard way to do this is to add a route for all the static files.
app.use(express.static("public"))
Right now, you are only sending home.html everytim the root is requested.
Change your code to read the requested file from the req and serve that file whatever it may be.
Why not set the middleware to serve static files (css, html) from public folder app.use(express.static("public"))
See the working example

JADE form submit not caught although route exists

I am using JADE, node.js, and express to create a table to select some data.
Everything is running on localhost.
When I try the route /climateParamSelect it works and displays what I would like to see including URL encoded elements.
Routing to this code snippet is in app.js but I confirmed that it works using /climateParamSelect?test=test. The routes are located in climateParamSelect.js
router.get('/', async function(req, res, next) {
console.log('GET');
console.log(req.query);
});
router.post('/', async function(req, res, next) {
console.log('POST');
console.log(req.params);
});
module.exports = router;
The code in app.js may be important after all, so here is an excerpt:
const express = require('express');
var tableSelectRouter = require('./routes/tableSelect');
var cpSelectRouter = require('./routes/climateParamSelect');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/climateParamSelect', cpSelectRouter);
app.use('/tableSel', tableSelectRouter);
When I use the submit button of the following page it is invoked but for some reason, the route above is never taken. Instead, it displays: waiting for localhost.
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel='stylesheet', href='https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css')
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js')
script(src='https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js')
script.
$(document).ready(function() {
$('#selTable').DataTable();
});
body
form(name='productionSelect', method='post', action='/climateParamSelect')
div#wrapper
h1 Select production data for feature generation
br
table#selTable.display
thead
tr
th headers
//...
tbody
tr
td
input(type='checkbox',id='#{r}',name='#{r}')
td
//...
br
input(type='submit',value='Select Production',name='prodSubmit',data-transition='fade', data-theme='c')
What am I missing here?
Thank you
The browser will sit there spinning until it receives a response, and there is no response sent in your route. I'm sure you'll want to render a view, but to test it quickly just use res.send and a string.
The second issue is in how you're reading the data sent from the client. req.params is used for dynamic URL parsing with variables in the route. To handle form data (which is what you're sending here) you can use req.body.
Changing your route to this should fix your issues:
router.post('/climateParamSelect', async function(req, res, next) {
console.log('POST');
console.log(req.body);
res.send("hello");
});

express.static only loading to index.html

I am trying to get the static files (images, js, css) which are all inside the public folder to be available to all my routes. I am able to ONLY load them to the index.html. The management.html files does not have access to the static files, I am getting 404 error on the Chrome console.
Folder Structure:
-app/
---index.html
---management.html
---public/
------css/
------js/
------img/
server.js:
const express = require('express');
const path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res) {
res.sendFile('index.html', {root: __dirname })
});
app.get('/management', function(req, res) {
res.sendFile('management.html', {root: __dirname })
});
app.listen(3000);
Inside your HTML files you are probably referring to the relative paths of the static files. For example: <img src="img/example.png">. This link will be based on your current location.
When your current location is http://example.com/ (index.html), then it will refer to http://example.com/img/example.png, where the file is probably located.
But when your location is http://example.com/management (management.html), it refers to http://example.com/management/img/example.png, which will return a 404.
Using the absolute path of this file will solve this problem. You can do this by putting a / in front of the relative path: <img src="/img/example.png">. Alternatively you could use a relative path in management.html like this: <img src="../img/example.png">.

Categories

Resources