GET method form with ExpressJS - multiple app.get - node.js

I want to make a simple login form.
This is the relevant code:
app.get('/login' , (req,res)=>{
app.use(express.static('login'));
res.render(__dirname + '/login/index.ejs');
/*This is load the login page*/
});
index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>login</title>
</head>
<body>
<h1>Login</h1>
<form action="/" method="GET">
<input type="text" name="email" placeholder="email">
<input type="password" name="password" placeholder="password">
<input type="submit" value="login">
</form>
</body>
</html>
You can see the form is GET method because I don't create/update anything. If I used app.post for detecting the parameters I've used app.post and it was working fine.
But how I handle two app.get ? one for load the page, the second for handle the html form ?
For example:
app.get('/login' , (req,res)=>{
console.log(req.query);
}
Thanks !

I recommend that instead of using the GET method for both the login and the displaying of your website you make your form method POST instead of GET. Then use multer in your express app as a way to parse the received form data.
<form action="/" method="POST">
const multer = require('multer');
const upload = multer();
app.use(upload.array());
app.post('/login', function(req, res){
console.log(req.body);
res.send("recieved your request!");
});

Related

Cannot load css file in ejs file

I am using an ejs file which is supposed to include a css file for styling, but the css file wouldn't load. Can someone help me resolve the issue. The server only loads the html view, but not css, despite using express.static() to serve the static files.
signup.ejs:
<!DOCTYPE html>
<html>
<head>
<title>Hostel</title>
<link rel="stylesheet" type="text/css" href="../assets/css/signup.css">
<link href="https://fonts.googleapis.com/css2?family=Jost:wght#500&display=swap" rel="stylesheet">
</head>
<body>
<div class="main">
<input type="checkbox" id="chk" aria-hidden="true">
<div class="signup">
<form>
<label for="chk" aria-hidden="true">Sign up</label>
<input type="text" name="txt" placeholder="User name" required="">
<input type="email" name="email" placeholder="Email" required="">
<input type="password" name="pswd" placeholder="Password" required="">
<button>Sign up</button>
</form>
</div>
<div class="login">
<form>
<label for="chk" aria-hidden="true">Login</label>
<input type="email" name="email" placeholder="Email" required="">
<input type="password" name="pswd" placeholder="Password" required="">
<button>Login</button>
</form>
</div>
</div>
</body>
</html>
app.js:
const express=require("express");
const connectDB = require("./db");
const app=express();
const path=require("path");
const userRouter=require("./routes/users");
app.use(express.json());
const port=process.env.PORT || 3000;
connectDB();
app.set('views', path.join(__dirname, '/views'));
app.set("view engine", "ejs");
app.use('/css', express.static(path.resolve(__dirname, "assets/css")));
app.use('/js', express.static(path.resolve(__dirname, "assets/js")));
app.use("/",(req,res,next)=>{
res.render("signup");
});
app.use("/users",userRouter);
app.listen(port,()=>{
console.log(`Server running on port ${port}`);
});
Folder Structure:
server
|
|->assets/css/signup.css
|->views/signup.ejs
|->app.js
Thank you in advance
Problem
The URLs in your HTML page don't match the express.static() middleware you have.
So, for example, when you have this:
<link rel="stylesheet" type="text/css" href="../assets/css/signup.css">
That's going to combine the path and domain of of the page URL to formulate a request to your server for something like:
/assets/css/signup.css
But, you don't have a route that matches that. You have this:
app.use('/css', express.static(path.resolve(__dirname, "assets/css")));
But, that requires a path that starts with /css and you have no route that starts with /assets.
Solution
So, drop the reference in the HTML page to /assets. That's an internal (to your server) location that the HTML page doesn't need to know anything about. In fact, you can technically change that on your server without breaking or changing the web page.
So, change your HTML tag to this:
<link rel="stylesheet" type="text/css" href="/css/signup.css">
This is an absolute path URL and will send a request for:
/css/signup.css
That will match your route here:
app.use('/css', express.static(path.resolve(__dirname, "assets/css")));
The /css part of the URL will match the app.use('/css', ...) route and after removing the /css part from the path, it will then look for the remaining page of the URL signup.css in the path.resolve(__dirname, "assets/css") directory.

Node.js (express framework): Post method not working

I am able to run the Get method and HTML form also visible on browser using Get method but when I am clicking on submit button nothing is happening, no error nothing. it shows the same HTML form page.
HTML code:
<!DOCTYPE html>enter code here
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Calculator</title>
</head>
<body>
<form action="/" method="post">
<h1>Calculator</h1>
<input type="text" name="num1" placeholder="Number 1">
<input type="text" name="num2" placeholder="Number 2">
<button action="/" type="button" name="button">Submit</button>
</form>
</body>
</html>
Node Js code:
//jshint esversion:6
const express=require("express");
const app=express();
app.get("/", function(req,res){
res.sendFile( __dirname+"/index.html");
});
app.post("/", function(req,res){
res.send("Thanks for post");
});
app.listen(3000, function(){
console.log("Server Started On Port 3000");
});
Your button type should be Submit
<button type="submit" value="Submit">Calculator</button>

EJS shows red mark when trying to embed data

i have this node server with express which directs data to different files like .ejs files and it worked before but I dont know what I did and so that it doesnt work, it marks every ejs's "<" in red.
im using VS CODE.
var app = express();
app.set('view engine', 'ejs');
app.get('/', function(req, res){
res.send("Hello wassup");
});
app.get('/homepage/:name', function(req,res){
res.render('home', {fullname : req.params.name});
});
app.get('/profile/:name', function(req, res){
var data = {Dummytext: "hey yo wassup and all that yea imma be right here tho",
hobbies : ['baskeall','computing','drawing', 'Learning', 'Driving'] };
res.render('profile', {fullname: req.params.name, data:data});
});
app.listen(4000);
and i have for example this ejs file that doesnt work
<!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>bla</title>
<link rel="stylesheet" type="text/css" href="partials/nav.css">
</head>
<body>
<% include partials/nav.ejs %>
<div class="user-info">
<div class="user-about">
<div class="user-name"><span><%= fullname %></span></div>
<div class="user-info_">
<div class="userimg">
<img src="/YDSign.png" alt="User profile" draggable="false" />
</div>
<div class="user-speech"><p><%= data.Dummytext%></p></div>
</div>
</div>
<div class="user-button">
<button type="button" class="friendAdd">Add Friend</button>
<button type="button" class="friendBell">Bell</button>
</div>
<div class="user-hobbies">
<div class="hobbies-list">
<h1>Hobbies</h1>
<div class="Upscroll"><img src="/iconList/ArrowUp.png" draggable="false"/></div>
<ul>
<% data.hobbies.forEach(function(item){ %>
<li><a><%= item %></a><img src="iconList/Hobbies.png" class="ident" /></li>
<% }); %>
</ul>
<div class="Downscroll"><img src="/iconList/ArrowDown.png" draggable="false" /></div>
</div>
</div>
</div>
Everything is fine.
You just should install plugin EJS language support in VSCode.
Just click CTRL+SHIFT+X and then write ejs in the search bar after that install the first one.
That works for me.

Localhost test: can't get resource using http://localhost:8888

For test purposes I run Apache local web server and I'm setting up a node.js app listening on port 8888 serving as image preprocessor, but unfortunately I'm experiencing problems as described below.
The node app.js is running in the web root directory:
'use strict';
let express= require('express')
,multer = require('multer')
,upload = multer()
,app = express()
//Import imgProcessor module which we would implement later
,imgProc = require('./imgProcessor');
app.get ('/', (req, res, next)=>{
res.sendFile(__dirname+'/appmain.html');
});
app.post('/uploadImg', upload.array('pics'),
(req, res, next)=>{
//Call the convertImgs method and pass the image files as its argument
imgProc.convertImgs(req.files).then(
(imageStringArray)=>{
//After all image processing finished, send the base64 image string to client
res.json(imageStringArray)})});
app.listen(8888, ()=>{
console.log('Hosted on Port 8888')});
The appmain.html page resides in the same web root directory:
<html>
<head>
<title>Upload Image Demo</title>
<link rel="shortcut icon" href="">
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/materialize-css/dist/js/materialize.min.js"></script>
<link rel="stylesheet" href="node_modules/materialize-css/dist/css/materialize.min.css">
</head>
<body class="container">
<div class="row">
<form id="form1" class="col m4 offset-m4" action="/uploadImg" enctype="multipart/form-data" method="post">
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input type="file" multiple="" accept="image/jpeg,png" name="pics">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload one or more files">
</div>
</div>
<div class="input-field">
<button type="submit" class="waves-effect waves-light btn">Submit</button>
</div>
<div class="progress" style="display:none">
<div class="indeterminate"></div>
</div>
</form>
</div>
<div class="row img-preview"></div>
<script>
$(function(){
$('#form1').on('submit', function(event){
event.preventDefault();
var data = new FormData(this);
$.each(
$('input[name="pics"]')[0].files,
function(i, file){
data.append('file-'+i, file);
});
$('.progress').css({
display:'block'
});
$.ajax({
type:'POST',
url: $(this).attr('action'),
data:data,
cache:false,
contentType: false,
processData: false,
success:function(data){
for(var i=0;i<data.length;i++){
var template =
'<div class="col m4">
<div class="card">
<div class="card-image">
<img src="'
+ data[i]
+ '"></div></div></div>';
$('.img-preview').append(template);
}
$('.progress').css({
display:'none'
});
},
error: function(err){
$('.progress').css({
display:'none'
});
}
});
})
})
</script>
</body>
</html>
When I use the URL http://localhost:8888 in the browser the html page is loaded (i.e. I can see the buttons and input fields of the form) but the resources requested in the <script> (ex.: node_modules/jquery/dist/jquery.min.js or node_modules/materialize-css/dist/js/materialize.min.js) are not loaded. By the same way the page can't benefit from the unloaded CSS stylesheet.
As opposite, if I try to use the URL http://localhost/appmain.html the page is loaded as expected (I mean: with the correct resources and CSS).
It seems that my Apache Web Server can't serve resources when handling the port number inside the URL. How can I resolve this?
EDIT
Just to simplify: let'say the node app2.js is listening on port 8888 and it has just a method (get) that send to the client the 'Hello World!' page app2main.html. No files to serve. The app2main.html page need only to load a couple of Javascript script and a CSS stylesheet.
app2.js
'use strict';
let express= require('express')
,app = express();
app.get ('/', (req, res, next)=>{
res.sendFile(__dirname+'/app2main.html');
});
app.listen(8888, ()=>{
console.log('Hosted on Port 8888')});
app2main.html
<html>
<head>
<title>Upload Image Demo</title>
<link rel="shortcut icon" href="">
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script
src="node_modules/materialize-css/dist/js/materialize.min.js"></script>
<link rel="stylesheet"
href="node_modules/materialize-css/dist/css/materialize.min.css">
</head>
<body class="container">
<h2> Hello World! </h2>
</body>
</html>
When accessing the URL http://localhost:8888 the 'Hello World!' message appears, but I get the following error (visibile by inspecting the page):
http://localhost:8888/node_modules/jquery/dist/jquery.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/js/materialize.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/css/materialize.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/css/materialize.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
Instead I get no error (and the expected style) when accessing the URL http://localhost/app2main.html
As discussed in comments, you should use express.static to serve static content in node.js app. In your case, your static content lies in node_modules directory itself. You can try the following code to load all resources,
e.g. http://localhost:8888/node_modules/jquery/dist/jquery.min.js
app.use('/node_modules', express.static('node_modules'));
Also, you mentioned that when you access http://localhost/app2main.html, then it worked without express.static, because apache web server to serve static files similar to express.static in node.js. That's why
http://localhost/node_modules/jquery/dist/jquery.min.js was working.
Hope it clears your doubt.

Managing Sessions in node

I'm learning how to use nodejs and i'm developing a chat page with my experience from php, i know that nodejs does almost nothing about what php does, so i'm building the whole structure, like rebuilding the php engine but just in node, for now im having problems with sessions, because i want to make a User system, so im making a login, it's quite hard for me to figure out what process to do in order to make a login process and if user exist, make the session, i have this code in my index
<!doctype html>
<html>
<head>
<title>Login - Chat</title>
<meta charset="UTF-8">
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<link rel="stylesheet" type="text/css" href="css/main.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
</head>
<body>
<div class="container" id="page">
<h2>Chat Login</h2>
<div id="login-form" class="well">
<form method="post" accept-charset="UTF-8">
<div class="form-group" method="post">
<label for="Username">Username</label>
<input type="text" class="form-control" id="Username" name="Username" placeholder="Enter email">
</div>
<div class="form-group">
<label for="Password">Password</label>
<input type="password" class="form-control" id="Password" name="Password" placeholder="Password">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<script type="text/javascript">
window.onload = init;
var socketio = io.connect(window.location.hostname);
function init()
{
var login = document.getElementById('login-form');
login.onsubmit = requestData;
}
function requestData()
{
username = document.getElementById('Username');
password = document.getElementById('Password');
//alert if form is empty.
if((username.value && password.value) == '')
{
alert('Box has empty value.');
return false;
}
else
{
socketio.emit('Login_user', {user: username.value, pass: password.value});
}
}
</script>
</body>
</html>
im using socket.io for transfering data from client to server and viceversa (im still learning it socket). I got stuck right in this step, i just need to know how to handle sessions in nodejs, i've got my github repository for this : Chat so you can see my whole code in there, any idea how to handle sessions?.
PD: I'm just a newbie developer, i have like 6 months using PHP and like 2 weeks with node, i dont want to use any framework in order to learn the language better.
I recommend using Express.js as node framework. Express has built in support via Connect framework. Im using this via a Redis backed session store to allow multi server load balancing. Here's a snippet on node-express-connect work in app.js if you want:
var express = require('express')
, RedisStore = require('connect-redis')(express)
;
var app = express();
app.use(express.session({
secret: 'some pass',
cookie: {
httpOnly: false,
secure: false,
maxAge:null,
domain:'.yourdomain.com'
},
store: new RedisStore({
ttl:1800, //30 min redis ttl
client:redis,
secret:'some pass'
})
}));
Since your using socket.io, I would recommend reading through the session.socket.io module. The source code is very small and readable:
README.md
session.socket.io.js (48 lines of code)

Resources