Serve static files using html string in express.js - javascript

I do frontend so I am sometimes lost when I am trying to do something on server.
I have this server.js file
const express = require('express');
const http = require('http');
const path = require('path');
const logger = require('morgan');
const renderPage = require('./layout');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const admin = require("firebase-admin");
var index = require('./routes/index');
// Initialize the Express App
const app = express();
// Apply body Parser and server public assets and routes
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.resolve(__dirname, 'public')));
app.use('/', index);
app.use((req, res, next) => {
res
.set('Content-Type', 'text/html')
.status(200)
.end(renderPage());
});
var server = http.createServer(app);
// start app
server.listen(3000);
module.exports = app;
..and this string template
const renderPage = (initialState) => {
return `
<!DOCTYPE html>
<html>
<head>
<link href="public/css/main.css"/>
<script src="some external javascript"/>
</head>
<body>
<div id="app"></div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};
</script>
</body>
</html>
`;
};
module.exports = renderPage;
When I start the server, it works, but css and script file do not work
Can you see what I am doing wrong?

Assuming your server.js file and your public directory exist at the same level, the path.resolve(__dirname, 'public') will build the full path to the public directory where all of your static resources should exist. When you reference these files inside your HTML pages you specify the path relative to the public directory.
<link href="css/main.css"/>
This should be enough to find the file. Assuming that file exists at ../public/css/main.css.

Related

Cannot GET / in node.js

index.js
const path = require("path");
const express = require("express");
const exp = require("constants");
const dotenv = require("dotenv").config();
const port = process.env.PORT || 5001;
const app = express();
//enable body parser
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//set static folder
app.use(express.static(path.join(__dirname, 'pubic')));
app.use('/openai', require("./routes/openaiRoutes"));
app.listen(port, () => console.log(`Server started on port ${port}`));
so I have 1 file index.js and in the public folder I have index.html file.
I am referring index.html in index.js through the path but when I run my localhost on port 5001 I get an error
Browser error
In the console
sorry I misspelled my public folder. My bad

Nodejs page (HTML) conversion, like how to changing the page when I click a button in main page jump to login page?

In my router code, I have something like below. In my main page, I have a button to jump to login page, that is work with out nodejs, but after I connect the node.js code, only show me the main page, if I click the login button, the page will show be that Cannot GET /LoginPage.html. How to fix that?
const express = require('express')
const router = express.Router()
router.get('/', (req, res) => {
res.render('HomePage.html', {
title: 'Hello World'
})
})
router.get('/login', (req, res) => {
res.render('LoginPage.html', {
title: 'Hello World'
})
})
In the app.js code:
const passport = require('passport')
const flash = require('express-flash')
const session = require('express-session')
const multer = require('multer');
const GridFsStorage = require("multer-gridfs-storage");
const path = require('path')
const cors = require('cors')
const crypto = require("crypto");
const favicon = require('serve-favicon')
const app = express();
const User = require('./models/user')
const router = require('./router')
app.engine('html', require( 'express-art-template'))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(express.static(__dirname + '/public'))
app.use('/node_modules/', express.static(__dirname + '/node_modules'))
app.use(cors());
app.use(router)
app.listen(4001, (req, res) => {
console.log('port xxxx')
})
In the HTML code, just click the button, and jump to Loginpage.html
Login
A couple of things,
you have 2 same endpoints router.get('/',
So change the second route to something like router.get('/login',
you should access your login page now on /login
You are getting Cannot GET /LoginPage.html because there is no route LoginPage.html in your backend
First thing is the way you defined the routes is wrong as you have 2 same end points.Try to change the login endpoint as /login in your .js file.
You need to change the html file also as you are trying to call directly the html file not the api end point /login.You need to call to the node backend endpoint which renders the desired html file.
not the direct reference to html file.
Edit 1:
Please do the following:
Change your app.js file like below:
const express = require('express');
const app = express();
const router = require('./router');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
app.engine('html', require('express-art-template'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use('', express.static(path.join(__dirname, 'public')));
app.use(cors());
app.use(router);
app.listen(4001, (req, res) => {
console.log('port 4001');
});
And the router.js to like this
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index.html', {
title: 'Hello World',
});
});
router.get('/login', (req, res) => {
res.render('login.html', {
title: 'Hello World',
});
});
module.exports = router;
And create a public folder and create 2 html files index.html and login.html. Your app structure should be like below:
--public
-------+ index.html
-------+ login.html
-- app.js
--router.js
--package.json
I tried this it worked for me. Change the variables and other file names as per your need. I guess your folder structure and the way you are rendering is wrong.Hopefully it should work.

Error when submitting form: Cannot POST using NodeJS + ExpressJS

I am new learning NodeJS + Express and now I am trying to build a simple register form but I keep getting the same error with this and other forms:
Cannot POST /registerauth
I have looked through dozens of similiar questions in stackoverflow and other sites but I have not found an answer that applies for my case.
Here is the form:
<form id="register-form" class="panel-form" action="/registerauth" method="POST">
<input type="text" name="register-username" id="register-username" class="fill-input" placeholder="Username *" autofocus="true" maxlength="15" required>
<input type="password" name="register-password" id="register-password" class="fill-input" placeholder="Password *" maxlength="30" required>
<button type="submit">Register</button>
</form>
My app.js file:
const express = require('express');
const app= express();
const path = require('path');
const port = process.env.PORT || 3000;
const login = require('./routes/login'); /*MODULE THAT HAS THE CONTROLLER CODE*/
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname , 'public')));
app.post('/registerauth',function (req,res,next){ /*TRIED THIS BUT DIDN'T WORK*/
console.log("testing");
res.json(req.body);
})
app.use('/login', login); /*TRIED CALLING THE MODULE THAT HAS THE CONTROLLER AND DELETING THE LINE ABOVE BUT DIDN'T WORK*/
app.listen(port, ()=> console.log(`server started on port ${port} `))
The module that has the controller code but it's not even called :
const express = require('express');
const oracledb = require('oracledb');
const router = express.Router();
const dbConfig =require('../dbconfig.js') ;
class Cliente{
constructor(username,password,nombre,email){
this.username = username;
this.password=password;
this.nombre=nombre;
this.email=email;
}
}
let conexion;
router.post('/registerauth',async(req,res,next)=>{ /*all this is not working neither*/
try{
console.log("THIS IS NOT WORKING");
cliente = new Cliente(req.body.username, req.body.password,req.body.nombre,req.body.email);
conexion= await oracledb.getConnection(dbConfig);
const result = await conexion.execute(
`INSERT INTO Cliente values (${cliente.username}, ${cliente.password},
${cliente.nombre}, ${cliente.email})`
);
} catch(err){
console.error(err);
}finally{
conexion.close();
}
})
module.exports = router;
And I have my project folder structured this way:
/
node_modules
public/
css/
media/
scripts/
index.html (just the file inside public folder)
register.html (just the file inside public folder THIS IS THE REGISTER FORM FILE)
routes/
api/
login.js
app.js
dbconfig.js
package-lock.json
package.json
Note: I created other forms in my project with different action methods and all of them gave the same error
this is the whole idea:
const express = require("express")
const app = express()
const router = require("./router")
app.use(express.static("public"))
app.use(express.urlencoded({extended: false}))
app.use(express.json())
app.use('/', router) // write all your routes in this file 'router'
module.exports = app
You need to render the HTML file in your server on port '3000'. I think you are trying to access 'http://localhost:3000/registerauth' directly while rendering the html page outside the server.
Make these changes to App.js file
const express = require('express');
const app= express();
const path = require('path');
const port = process.env.PORT || 3000;
const login = require('./routes/login'); /*MODULE THAT HAS THE CONTROLLER CODE*/
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
//newly added code
app.get('/',(req,res)=>{
res.sendFile('index.html');
})
app.post('/registerauth',function (req,res,next){ /*TRIED THIS BUT DIDN'T WORK*/
console.log("testing");
res.json(req.body);
// Redirect to '/login' here instead of sending response which will trigger the login module
})
app.use('/login', login); /*TRIED CALLING THE MODULE THAT HAS THE CONTROLLER AND DELETING THE LINE ABOVE BUT DIDN'T WORK*/
app.listen(port, ()=> console.log(`server started on port ${port} `))
Render the html page when you hit 'http://localhost:3000'. Also, inorder for your login component to work you need to redirect to '/login/' path in the POST request

CSS seems to be sent to page, but nothing applies [ExpressJS + Handlebars]

I am attempting to do a very simple page with Handlebars and Express with NodeJS, however I am running into difficulty getting it to display css. It seems that the browser is receiving the CSS file given the feedback and the 200 code I'm getting in my Node window, but no effect is shown on the actual page.
file structure
app.js
/public
/stylesheets
style.css
/views
/layouts
main.handlebars
home.handlebars
app.js
var express = require('express');
var exphbs = require('express-handlebars');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
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')));
var person = {
name:"Clay",
age:"20",
attr:["tall","handsome","wearing a red sweater"]
}
app.get('/', function (req, res, next) {
res.render('home', {layout: false, people: person});
});
module.exports = app;
main.handlebars
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Database</title>
<link rel="stylesheet" href="stylesheets/style.css" />
</head>
<body>
{{{body}}}
</body>
</html>
home.handlebars
<h1>Example App: Home</h1>
hello world
style.css
body {
background-color: red;
}
node console

req.app.get('db') is undefined when using Massive JS in my Node Application

I am building a Node application using Express, Massive JS, and Postgresql. I was using sequelize but decided to try Massive JS, so I started converting my code to use it.
I have a login endpoint that I'm trying to reach from my Angular 5 app and I am getting an error. This error only occurs on my deployed application. It does work locally without any issues.
Here is the specific error:
TypeError: Cannot read property 'get_user' of undefined<br> at login (/root/firstImpression/server/features/auth/authController.js:7:26)
Here is my folder structure:
+Server
-server.js
+config
-secrets.js
+db
-get_user.sql
+features
+auth
-authController.js
-authRoutes.js
server.js file contents:
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
const cookieParser = require('cookie-parser');
const secrets = require('./config/secrets');
const massive = require('massive');
// used to create, sign, and verify tokens
var jwt = require('jsonwebtoken');
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use(cookieParser());
//routes
require('./features/auth/authRoutes')(app);
//Connect to database
massive(secrets.development).then(db => {
app.set('db', db);
});
// Angular DIST output folder
app.use(express.static(path.join(__dirname, '../dist')));
//Set up static files
app.use(express.static('../dist'));
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../dist/index.html'));
});
//Set Port
const port = process.env.PORT || '3000';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`Running on localhost:${port}`));
get_user.sql file contents:
SELECT * FROM users WHERE username = $1;
authController.js file contents:
const jwt = require('jsonwebtoken');
const secrets = require('../../config/secrets');
const bcrypt = require('bcrypt');
module.exports = {
login: (req, res) => {
req.app.get('db').get_user(req.body.username).then(user => {
if(user[0]) {
bcrypt.compare(req.body.password, user[0].password,
function(err, result) {
if(result) {
var token = jwt.sign({user}, secrets.tokenSecret,
{expiresIn: '1h'});
res.status(200).json({
token: token,
user: user
})
} else {
res.status(200).json("Invalid username and/or
password.");
}
});
} else {
res.status(200).json("Could not find that user.");
}
})
}
}
authRoutes.js file contents:
var authController = require('./authController');
module.exports = (app) => {
app.post('/user-auth', authController.login);
}
The error is occuring in the authController.js file on this line:
req.app.get('db').get_user(req.body.username)
I've been reading the docs for massive js and learned the importance of keeping the DB folder on the same level where it's initialized, which is my server.js file.
As I stated earlier, when I run this on my local machine, it works great; However as soon as I deploy it to my live environment, I receive the error.
Any help or direction would be greatly appreciated. Let me know if any other information is required, and I will gladly provide it.
Your app setup should probably be wrap like
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
const cookieParser = require('cookie-parser');
const secrets = require('./config/secrets');
const massive = require('massive');
// used to create, sign, and verify tokens
var jwt = require('jsonwebtoken');
//Connect to database
massive(secrets.development).then(db => {
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use(cookieParser());
app.set('db', db);
// Angular DIST output folder
app.use(express.static(path.join(__dirname, '../dist')));
//routes
require('./features/auth/authRoutes')(app);
//Set up static files
app.use(express.static('../dist'));
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../dist/index.html'));
});
//Set Port
const port = process.env.PORT || '3000';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`Running on localhost:${port}`));
});

Categories

Resources