Serving static files in express net::ERR_FILE_NOT_FOUND - node.js

My folder structure is :
APP
-public
main.js
-views
index.html
index.js
I am trying to serve the static file to express server but its not working. The code for this in my index.js file is:
const express = require('express'),
app = express();
app.use(express.static(__dirname+'/public'));
I have also tried using path.join syntax
In my index.html file in the views folder , I am using the src tag as 'main.js'
<script type="text/javascript" src="main.js"></script>
I get the error net::ERR_FILE_NOT_FOUND.
I can also see that path src is referring to is wrong.
It is looking for main.js file in views directory instead of looking in public directory.
I have looked at other answers. I understand the syntax theoretically but am not able to find what I am doing wrong
Please point out the issue in my code. Thanks

Here is a working example:
index.js:
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;
app.use(express.static(__dirname + '/public'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, './views/index.html'));
});
app.listen(port, () => console.log(`server is listening on port ${port}`));
./public/main.js:
window.onload = function() {
console.log('onload');
};
./views/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script type="text/javascript" src="main.js"></script>
</head>
<body>
This is template
</body>
</html>

Related

Nginx/Nodejs/Handlebars static files 404

I have a nodejs app with handlebars, and an nginx reverse proxy sitting on an ubuntu server. No matter what combination of app.use(express.static('public')) and linking stylesheets I use, I only get a 404 on the stylesheet. Here's my code:
const express = require('express')
const path = require('path');
const hbs = require('hbs');
const app = express();
app.set('view engine', 'hbs');
app.use(express.urlencoded({ extended: true }))
app.use(express.static('public'));
hbs.registerPartials(path.join(__dirname, 'views/partials'));
app.get('/', async (req, res) => {
if (req.query.prompt) {
prompt = req.query.prompt;
}
res.render('index', {
prompt: prompt,
});
})
app.listen(8080, () => console.log('Listening on port 8080.'))
And this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
<img src="profile.jpg" alt="photo">
</body>
</html>
Any help would be much appreciated! And yes, there are a lot of potential duplicates to this question but nothing has helped me :/
I've tried all combinations of /public, /index.css, /public/index.css etc.
My file structure looks like this:
I found the fix, and it wasn't nodejs or handlebars--it was removing the following line in my server block:
try_files $uri $uri/ =404;
I'll leave this here for anyone who might find this useful.

script source not found, in node.js when trying https connection

im trying to reference socket.io in my login.html but it gives following error:
GET https://localhost:3000/socket.io.js net::ERR_ABORTED 404 (Not Found)
i think its because this code line in my login.html :
<script src='/client-dist/socket.io.js'></script>
i was trying other reference the script in other ways, but those doesnt work. it worked when my server.js was a http connection, but now i need a https connection.
its also dont possible to reference oder javascript refrences.
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<section>
<h1>Login</h1>
<p>
username:<input id="username">
<br>
password:<input id="password">
<br>
</p>
<p>
<button onclick="window.location.href='/register'">Create Account</button>
</p>
<button id="submitButtonLogin" onclick="onClick()">submit</button>
</section>
<script src='/client-dist/socket.io.js'></script>
</body>
</html>
server.js:
const express= require('express')
const app= express();
//const path= require('path')
const https= require('https')
const io=require('socket.io')(https,{maxHttpsBufferSize:1e8})
const fs=require('fs')
const sslServer =https.createServer({
key: fs.readFileSync('cert/key.pem'),
cert: fs.readFileSync('cert/cert.pem')
},app)
const PORT=process.env.PORT || 3000
sslServer.listen(PORT, ()=>{
console.log(`listening to port ${PORT}`)
});sslServer.setTimeout(0)
app.get('/test', (req,res)=>{
res.sendStatus(200);
})
app.use(express.static(__dirname + '/public'))
app.use(require('./routes/posts'));
app.use(require('./routes/users'));
app.get('/',(req,res)=>{
res.sendFile(__dirname + '/login_register/login.html')
})
app.get('/register',(req,res)=>{
res.sendFile(__dirname + '/login_register/register.html')
})
app.get('/chatroom',(req,res)=>{
res.sendFile(__dirname + '/index.html')
})
my hierarchy:
chatapplication
-cert
cert.pem
csr.pem
key.pem
-login_register
login.html
register.html
-model
user.js
-node_modules
(included when setup)
-public
client.js
style.css
-routes
users.js
database.js
index.html
package-lock.json
package.json
secret.json
server.js

Express Javascript file won't including with get method with parameters

I'm trying render the index file with Express Node.js successfully, but if I'm using namespaces with parameter, without parameter render twig file and included own scripts, if I use try with parameter, render ok bu problem with script files path so script files in head in html cannot including while path not correct
for example, without parameter, in html file style.css look like
<link rel="stylesheet" href="style.css"> path http://127.0.0.1:3000/style.css
with parameter, in html file style.css look like <link rel="stylesheet" href="style.css"> path http://127.0.0.1:3000/mynamespace/style.css <--- and this not found!
say browser path not found!
Server.js
const port = 3000;
const express = require('express');
const app = express();
const http = require('http');
const socketIO = require('socket.io');
const server = http.Server(app);
server.listen(this.port, () => {
console.log(`Server running on: http://127.0.0.1:${port}`);
});
const io = socketIO(server);
app.set('view engine', 'twig');
app.set('views', "views");
app.use(express.static('public'));
app.use(express.static('scripts'));
app.use(express.static("styles"));
/// Routing
/**
* This work fine
* Render client.twig
* Including Scripts in head
*/
app.get('/mynamespace', function (req, res, next) {
res.render("client");
});
/**
* This work with error
* Render client.twig
* don't Including Scripts in head
*
*/
app.get('/mynamespace/:id', function (req, res, next) {
res.render("client");
});
io.of("/mynamespace").on('connection',(socket)=>{
socket.on('online_users', (data) => {
console.log(`Online Users ${data}`);
});
});
client.js
let url = `http://127.0.0.1:3000/mynamespace`;
console.log("Url", url);
this.socket = io(url);
this.socket.on("connect", ()=>{
try{
this.socket.emit('welcome', {
message:"Welcome guest"
});
} catch (e) {
alert(e.message);
}
});
client.twig
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" const="text/html;charset=UTF-8"/>
<title>RestoCommend</title>
<script src="/socket.io/socket.io.js"></script>
<link rel="stylesheet" href="style.css"
</head>
<body>
<h3>Client</h3>
<script src="helper.js"></script>
<script src="client.js"></script>
</body>
</html>
From your code it looks like the style.css file is in the same directory as client.twig which is the views directory. But you have told express that the static directories are public, scripts and styles. There is no instruction for express to know where to serve the css from. Try moving the style.css file into styles directory.
Good luck.
Sounds like you want to serve your static files under a relative path. Try the following:
app.use('/mynamespace', express.static('public'))
app.use('/mynamespace', express.static('scripts'))
app.use('/mynamespace', express.static('styles'))
And also
<link rel="stylesheet" href="mynamespace/style.css" />
My hierarchy of files
I Solved my problem, but not good idea
Server.js
app.get('/mynamespace1', function (req, res, next) {
app.use(express.static('public'));
app.use(express.static('scripts'));
app.use(express.static("styles"));
res.render("client1");
});
one parameter based namespace!
app.get('/mynamespace2/:clientId', function (req, res, next) {
app.use(express.static(path.join( __dirname + "/../", 'public')))
app.use(express.static(path.join( __dirname + "/../", 'scripts')))
app.use(express.static(path.join( __dirname + "/../", 'styles')))
res.render("client2");
});
more as one parameter based namespace!
app.get('/mynamespace3/:roomName/:clientId', function (req, res, next) {
app.use(express.static(path.join( __dirname + "/../", 'public')))
app.use(express.static(path.join( __dirname + "/../", 'scripts')))
app.use(express.static(path.join( __dirname + "/../", 'styles')))
res.render("client3");
});
client1.twig
<link rel="stylesheet" href="style.css">
<script src="helper.js"></script>
<script src="client.js"></script>
Everything normal
client2.twig
<script src="/socket.io/socket.io.js"></script>
<link rel="stylesheet" href="../style.css">
<script src="../helper.js"></script>
<script src="../client.js"></script>
with one prameter, script paths defined to parent
client3.twig
<script src="/socket.io/socket.io.js"></script>
<link rel="stylesheet" href="../../style.css">
<script src="../../helper.js"></script>
<script src="../../client.js"></script>
with more prameters, parent folder defined, until number of parameter
My Problem solved, but I don't like it so

Why is app.use() not serving up the 'public' directory when I save even though the path is appears to be correct?

I'm following a slightly outdated tutorial on node and express, and my code is identical to the tutorial, but app.use is not serving up the public directory as I wish. When I go to the root localhost:3000 I still see Weather like in the tags on line 19. When I delete it, I don't see anything, including the public directory's index.html file.
Here is my index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> -->
<title>Document</title>
</head>
<body>
<h1>From a static file.</h1>
</body>
</html>
Here is my app.js script:
/* nodejs script that will create, configure, and start the server.
run script: node src/app.js
keep server running: nodemon src/app.js
*/
const path = require('path');
const express = require('express');
const app = express();
const publicDirectoryPath = path.join(__dirname, '../public'); // abs path to serve
// STACKOVERFLOW - WHY ISN'T THIS SERVING UP PUBLIC DIRECTORY?
app.use(express.static(publicDirectoryPath)); // serve 'public' directory
// create root route
app.get('/', (req, res) => {
res.send('<h1>Weather</h1>');
});
// create a help route
app.get('/help', (req, res) => {
res.send([
{name: 'Barack H. Obama'},
{name: 'George W. Bush'},
{name: 'William J. Clinton'}
]);
});
// create an about route
app.get('/about', (req, res) => {
res.send('<h1>About</h1>');
});
// create a weather route
app.get('/weather', (req, res) => {
res.send({
forecast: 'rain',
location: 'Los Angeles'
});
});
// port 3000 is common development port, starts server
app.listen(3000, () => {
console.log('Server is up on port 3000'); // never displays in browser
});
it should be public instead ..public like this
const publicDirectoryPath = path.join(__dirname, 'public')
As app.js and public share the same parent directory at the same level. So ..public will point out to dir public outside src which is not available.

app.get('/') data doesn't show in same url using app.use('/') in express

This Link is explaining difference with app.use and app.get. But not explaining about same route problem. So I want to ask my question.
I made react project with create-react-app and make server inside src folder. I want to show text in the index.html when url is root. So I write codes like this.
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
</head>
<body>
<p>Html test</p>
</body>
</html>
src/server/server.js
import express from 'express';
import path from 'path';
const app = express();
const port = 4000;
app.use('/', express.static(path.join(__dirname, '../../public')));
app.get('/', (req, res) => {
return res.send('<p>Hello index</p>');
});
app.get('/hello', (req, res) => {
return res.send('Hello CodeLab');
});
app.listen(port, () => {
console.log('Express is listening on port', port);
});
package.json
"babel-node": "babel-node src/server/server.js --presets es2015"
I test,
localhost:4000/hello --> Hello CodeLab
localhost:4000/ --> Html test (not Hello index)
I thought app.use is just static file which called every time when same url is called by app.get. Why app.get('/')doesn't show <p>Hello index</p> in this project?
Why app.get('/') doesn't show <p>Hello index</p> in this project?
It depends on the order. Re-write like this:
app.get('/', (req, res) => {
return res.send('<p>Hello index</p>');
});
app.use('/', express.static(path.join(__dirname, '../../public')));
You will get <p>Hello index</p> for sure!
The reason is under the hood, app.use() and app.get() both behave just like middlewares, they are treated equally in the Express app. The appear order decides which one is executed first.
an app is an object initialized on the start of express. app.use is for setting midleware More info
to resolve this problem just remove match for a route:
app.use(express.static(path.join(__dirname, '../../public')));
With '/' in app.use you must use next() method then express will go to next controller.

Resources