I'm trying to build a login page for users and need to send the login info to my express server. I'm not too sure about how to call the api for my server and send the information across though.
Right now I get a 405 error method not allowed when I try to submit the form by clicking on the button.
index.html:
<!DOCTYPE html>
<html land="en">
<head>
<meta charset="UTF-8">
<title>Home page</title>
<script src="../app.js"></script>
</head>
<body>
To login
</body>
</html>
login.html:
<!DOCTYPE html>
<html land="en">
<head>
<meta charset="UTF-8">
<title>Login page</title><br><br>
<script src="../app.js"></script>
</head>
<body>
<form id="login-form" method="post" action="/login">
<input type="text" name="username" id="username-field" placeholder="Username" required><br><br>
<!-- TODO: Change type to "password" -->
<input type="text" name="password" id="password-field" placeholder="Password" required><br><br>
<input type="submit" value="Login" id="login-form-submit">
</form>
</body>
</html>
app.js:
const express = require('express')
var bodyParser = require('body-parser')
var port = process.env.PORT || 3000;
var app = express();
app.use(express.json());
app.use(express.urlencoded({"extended": true}));
app.get('/', function (req, res) {
res.render(__dirname + '/views/index.html');
});
app.post('/login', function (req, res) {
res.statusCode = 200;
res.send({ 'body': req.body });
});
// Listen on port 3000, IP defaults to 127.0.0.1
app.listen(port, () => {
console.log('Server listening at http://127.0.0.1:' + port + '/');
});
You can do it using javascript. Add this to your login.html file
<script type="text/javascript" >
async function login(){
// Get values from FORM
let username = document.getElementById("username-field")
let password = document.getElementById("password-field")
// Body payload
let body = { username, password }
// Fetch options
let option = {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json'
}
}
// Call /login as POST and wait for reply
const response = await fetch(`/login`, options)
const json = await response.json()
// Use json response
alert(json)
}
document.getElementById("login-form-submit").addEventListener("click", login);
</script>
In order for the server to be properly up, you need to make sure you run it as node app.js instead of adding it to the html file.
UPDATE:
Check out this repo for a working solution : https://github.com/rui-costa/stackoverflow-68238492
Related
I am trying to create a calculator app using express.js to get request for an html file and a post request that takes the user's input and responds with the answer. However, I want to display my answer inside a html container without the page redirecting. Is there a way to achieve this with vanilla javascript?
index.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="styles.css" />
<link rel="shortcut icon" href="#" />
<title>Calculator</title>
</head>
<body>
<h1>Calculator App</h1>
<form action="/" method="post" class="ajax">
<label for="userInput">Enter Equation</label>
<input type="text" id="equation" name="equation" />
<button type="submit" id="btn_submit">Calculate</button>
</form>
<div class="container"></div>
</body>
</html>
app.js
const express = require('express');
const app = express();
port = 3000;
app.use(express.urlencoded({ extended : false }));
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile(__dirname + public);
});
app.post('/', (req, res) => {
let equation = req.body.equation;
console.log(equation);
let result = eval(equation);
res.status(200).send('Result is ' + result);
});
app.listen(port, ()=> {
console.log('Hosted on port: ' + port);
});
CalculatorApp
Evaluated Expression
You will need to write front end JavaScript code to make the ajax request instead of having the form action submit the request. The JavaScript will receive the response and can update the value on the HTML.
app.post('/', (req, res) => {
let equation = req.body.equation;
console.log(equation);
let result = eval(equation);
res.status(200).json({ value: `Result is ${result}` });
});
<script>
document.querySelector('form').addEventListener('submit',submitEquation);
function submitEquation(event){
event.preventDefault();
const input = document.querySelector('#equation');
const equation = input.value;
const clearInput = true;
if(clearInput){
input.textContent = '';
}
fetch(window.location.origin, {
method: 'post',
body: JSON.stringify({ equation })
})
.then(response => response.json())
.then(json => {
document.querySelector('.container').textContent = json.value;
})
}
</script>
Please educate me about how am I going to connect the CSS to the server. I've followed two tutorials on youtube, one is using node.js and nodemailer. With this, I use a localhost to run my website but the CSS and js I made from the second tutorial (pop-up when button is clicked) won't work on the localhost but when I clicked the html file itself.
Is this because the tutorials are for different kinds of website? like static and dynamic?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="style.css" rel="stylesheet" type="text/css" />
<title>Document</title>
</head>
<body>
<h1>Welcome to my App</h1>
<form>
<div>
<label for="email">Sender's Email: </label>
<input type="email" id="email" placeholder="Your Email"> <br>
</div>
<div>
<label for="classNum">To whom: R</label>
<input type="number" id="classNum" placeholder="class#" min="1" max="31"> <br>
</div>
<div>
<label for="subject">Subject: </label>
<input type="text" id="subject" placeholder="Subject"> <br>
</div>
<div>
<label for="text">Letter: </label> <br>
<textarea name="text" id="text" cols="30" rows="10"></textarea> <br>
</div>
<input type="submit" value="Submit" class="modal-button" data-modal-target="#modal">
<div class="modal" id="modal">
<div class="modal-header">
<div class="title">Letter Sent!</div>
</div>
<div class="modal-body">
Pressing this button will refresh the page.
<div><button data-close-button class="refresh-button">Send another letter</button></div>
</div>
</div>
<div id="overlay"></div>
</form>
<script src="script.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$('form').on('submit', (e) => {
e.preventDefault();
const email = $('#email').val().trim();
const subject = $('#subject').val().trim();
const text = $('#text').val().trim();
const classNum = $('#classNum').val().trim();
const data = {
email,
subject,
text,
classNum
};
$.post('/email', data, function(){
console.log('Server received our data')
});
});;
</script>
</body>
</html>
This is the server.js
const express = require('express');
const sendMail = require('./mail')
const log = console.log;
const app = express();
const path = require('path');
const PORT = 8080;
app.use(express.urlencoded({
extended: false
}));
app.use(express.json());
app.post('/email', (req, res) => {
const { subject, email, text, classNum} = req.body;
console.log('Data: ', req.body);
sendMail(email, subject, text, classNum, function(err, data){
if (err){
res.status(500).json({ message: 'Internal Error'});
}
else{
res.json({ message: 'Email sent!' });
}
});
// res.json({ message: 'Message received!' })
});
app.get('/', (req, res) =>{
res.sendFile(path.join(__dirname, 'views', 'index.html'));
});
app.listen(PORT, () => log('Server is starting on PORT: ', 8080));
And this one is for the pop-up, script.js
const openModalButtons = document.querySelectorAll('[data-modal-target]');
const closeModalButtons = document.querySelectorAll('[data-close-button]');
const overlay = document.getElementById('overlay');
var path = require('path') //from stackoverflow
app.use(express.static(path.join(__dirname, 'public')));
openModalButtons.forEach(button => {
button.addEventListener('click', () => {
const modal = document.querySelector(button.dataset.modalTarget)
openModal(modal)
})
})
closeModalButtons.forEach(button => {
button.addEventListener('click', () => {
const modal = button.closest('.modal')
closeModal(modal)
})
})
function openModal(modal) {
if (modal == null) return
modal.classList.add('active')
overlay.classList.add('active')
}
function closeModal(modal) {
if (modal == null) return
window.open("https://www.w3schools.com");
}
Please tell me if I need to include the CSS and the mail.js .
If you want to allow users or browsers to get files from your server, you need to add them to your server-side code. For example, you've added a stylesheet reference to your index.html, so the browser will try to get that file (/style.css) from the server. You haven't put any reference to this on the server side, so the server will respond with 404 Not Found or another error.
In order to make the server respond to a request for "/style.css", you need to add the following to your server-side index.js:
app.get("/style.css" /*name of file in index.html*/, (req, res) => {
res.sendFile(path.join(__dirname, 'views', 'style.css')); //CHANGE THIS TO THE NAME OF THE FILE ON THE SERVER
});
The same needs to happen for your browser script, script.js:
app.get("/script.js" /*name of file in index.html*/, (req, res) => {
res.sendFile(path.join(__dirname, 'views', 'script.js'));
});
app.get tells express to respond to a GET request to the first parameter: in the example, that's "/style.css". If you wanted to respond to a GET request to "/foobar", then you would write app.get("/foobar", (req, res) => {/*SOME CODE HERE*/}); . The reason why it wasn't working was becuase when the browser tried to find style.css and script.js, the server didn't know what to do because you hadn't included app.get for those files, and therefore responded with an error.
This might be confusing due to the architecture of how this works. Look at this diagram:
==== HOW A WEBSITE SENDS A FILE ====
______ ____ ______
/ . . \ GET /file [____] READ / |
| j | ======> [____] ======> | file |
\__===_/ <====== [____] <====== | |
user RESPONSE server |_______|
When I click the subscribe button it redirects my page to 127.0.0.1 and nothing appears in console.log. Why is that
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Abonelik</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
<link rel="stylesheet" href="signin.css">
</head>
<body>
<div class="parent-wrapper">
<span class="close-btn glyphicon glyphicon-remove"></span>
<div class="subscribe-wrapper">
<h4>Abone Olun</h4>
<form action="/" method="POST">
<input type="text" name="fname" class="subscribe-input" placeholder="Adınız">
<input type="text" name="lname" class="subscribe-input" placeholder="Soyadınız">
<input type="email" name="email" class="subscribe-input" placeholder="Mail Adresiniz">
<button type="submit">Abone Ol</button>
</form>
</div>
</div>
</body>
</html>
Nodejs
//jshint esversion:6
const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const https = require("https");
const app = express();
app.use(express.static("public"));
app.use(bodyParser.urlencoded({
extended: true
}));
app.get("subs", function(req, res) {
res.sendFile(__dirname + "/signup.html");
});
app.post("/", function(req, res) {
const mail = req.body.email;
const ilkad = req.body.fname;
const soyad = req.body.lname;
console.log(fname, lname, email);
const data = {
members: [{
email_address: mail,
status: "Subscribed",
merge_fields: {
FNAME: fname,
LNAME: lname,
}
}]
};
const jData = JSON.stringify(data);
const url = "https://usX.api.mailchimp.com/3.0/lists/";
const option = {
method: "post",
auth: ""
};
const request = https.request(url, options, function(response) {
response.on("data", function() {
console.log(JSON.parse(data));
});
});
request.write(jData);
request.end();
});
app.listen(3000, function() {
console.log("Server Çevrimiçi");
});
I just wanted to apply the subscribe button a function to send data to the hyper terminal when the user logs mail name surname etc. but when I click it redirects me to 127.0.0.1 which is local folder. and I am almost sure that there is something wrong between app.get and form direction but I don't know how to solve this problem. I know it is a long post sorry for that but I really appreciate some help. thank you.
You are printing the wrong variables. Since you do this:
const mail = req.body.email;
const ilkad = req.body.fname;
const soyad = req.body.lname;
you should print the data from request by:
console.log(ilkad, soyad, email);
Also, a good practice is using the object destructuring like this:
const {email, fname, lname} = req.body
and then use:
console.log(fname, lname, email);
So this is my server.js file, where the db is being connected to :
var app = require('express')();
var mysql = require('mysql');
var db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'user_data',
port: 3306
});
db.connect();
app.get('/', function (req, res) {
res.sendFile(__dirname + "/start.html");
});
app.listen(3000);
So I want to make something like a registration form, where you input your username and password. Then, after you click the submit button, the username and password are supposed to go straight to the mySQL database. So apparently, I need an ajax call which sends the data to that server, but I don't know how to access it on the server.js.
$("button#submit").click(function () {
$.ajax({
'url': 'http://localhost:3000',
'type': 'post',
'data': {
'username': $("#usr").val(),
'password': $("#pwd").val()
},
'success': function (data) {
alert('Data: ' + data);
}
});
})
After I get that data on the server.js, I will obviously want to make a query (to insert the values) but how do I get the data?
This is how I did it for one of my projects:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Contact Form</title>
</head>
<body>
<div id="contact">
<h1>Send an email</h1>
<form action="/myaction" method="post">
<fieldset>
<label for="name">Name:</label>
<input type="text" id="name" name="name" placeholder="Enter your full name" />
<label for="location">Location:</label>
<input type="text" id="location" name="location" placeholder="Enter your location" />
<input type="submit" value="Send message" />
</fieldset>
</form>
</div>
</body>
</html>
Now when user clicks submit /myaction url will hit.
db.connect(function(err,connection){
app.post('/myaction',function(req,res){
console.log(req.body);
var employee={name:req.body.name,location:req.body.location}
db.query('INSERT into employees SET ?',employee,function(err,res){
if(err){
throw err;
}
else{
console.log(res);
}
})
res.send(JSON.stringify(req.body));
})
})
Make sure to include these in your server.js
var express=require('express');
var bodyParser=require('body-parser');
app=express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
So you can see i have defined app.post and I am hitting my url. Then we simply write a sql query to store data.
I am trying to understand where to locate the logic to send an email via a contact form in my Angular App (using angular-fullstack MEAN stack from Yeoman).
I can add the logic to send an email in the app.js file on the server side using nodemailer and sendgrid and everything works and an email is sent every time I refresh the server, however I am a little fuzzy on where to place the logic so that it only gets sent once the form is submitted and it hits the server side.
This is what the create action looks like on the Express JS side...
exports.create = function(req, res) {
Contact.create(req.body, function(err, contact) {
if(err) { return handleError(res, err); }
return res.json(201, contact);
});
};
Here is the code in app.js that is working, but obviously not in the right place...
var nodemailer = require('nodemailer');
var sgTransport = require('nodemailer-sendgrid-transport');
var options = {
auth: {
api_user: 'username', // 'SENDGRID_USERNAME' - Recommended to store as evn variables
api_key: 'password', // 'SENDGRID_PASSWORD'
}
};
var mailer = nodemailer.createTransport(sgTransport(options));
var email = {
to: 'sendto#email.com',
from: 'sendfrom#email.com',
subject: 'Test Email',
text: 'Awesome Email',
html: '<b>Bold and Awesome Email</b>'
};
mailer.sendMail(email, function(err, res) {
if (err) {
console.log(err)
}
console.log(res);
});
Coming from a rails background my initial thought is to stick the logic in the create action so that if the object is created successfully the email gets sent. Is this a correct way of thinking about it in this scenario...I am new to the MEAN stack.
Thanks for any help...
You need to create a route on the server that you can post form values to from Angular using $http.post.
The following lets you enter details in an Angular form. The form is then posted to Node where the req.body values are extracted and added email object. The email is then send by SendGrid.
SERVER.JS
var express = require('express');
var http = require('http');
var bodyParser = require('body-parser');
var dotenv = require('dotenv');
dotenv.load(); //load environment variables from .env into ENV (process.env).
var sendgrid_username = process.env.SENDGRID_USERNAME;
var sendgrid_password = process.env.SENDGRID_PASSWORD;
var sendgrid = require('sendgrid')(sendgrid_username, sendgrid_password);
var email = new sendgrid.Email();
var app = express();
app.use(bodyParser.json()); //needed for req.body
app.set('port', process.env.PORT || 3000);
app.use(express.static(__dirname + '/public'));
app.post('/email', function(req, res) {
email.addTo(req.body.to);
email.setFrom(req.body.from);
email.setSubject(req.body.subject);
email.setText(req.body.text);
email.addHeader('X-Sent-Using', 'SendGrid-API');
email.addHeader('X-Transport', 'web');
sendgrid.send(email, function(err, json) {
if (err) {
return res.send("Problem Sending Email!!!!");
}
console.log(json);
res.send("Email Sent OK!!!!");
});
});
var server = http.createServer(app);
server.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port') ) ;
});
INDEX.HTML
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title></title>
<!-- CSS -->
</head>
<body ng-controller="MainCtrl">
<form name="emailForm">
<div class="group">
<input type="email" name="to" ng-model="email.to" ng-required="true">
<label>To</label>
</div>
<div>
<input type="email" name="from" ng-model="email.from" ng-required="true">
<label>From</label>
</div>
<div>
<input type="text" name="subject" ng-model="email.subject" ng-required="true">
<label>Subject</label>
</div>
<div>
<textarea ng-model="email.text" name="text" placeholder="Enter Text Here.."></textarea>
</div>
<button id="emailSubmitBn" type="submit" ng-click="submitEmail()">
Submit
</button>
</form>
<!-- JS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
CLIENT SIDE APP.JS
angular.module('myApp', [])
.controller('MainCtrl', function($scope, $http) {
$scope.submitEmail = function() {
console.log("TEST");
//Request
$http.post('/email', $scope.email)
.success(function(data, status) {
console.log("Sent ok");
})
.error(function(data, status) {
console.log("Error");
})
};
});