I just started learning Node and Express for a simple project but for some reason I cannot get POST to work. My browser gives me an error: Cannot POST /
Any assistance with this issue is appreciated. Thank you.
My code is below:
let express = require("express")
let ourApp = express()
ourApp.use(express.urlencoded({ extended: false }))
ourApp.get("/", function(req, res) {
res.send(`
<form action='/' method='POST'>
<h2>What color is the sky on a clear and sunny day?</h2>
<input name="skyColor" autocomplete="off">
<button>Submit Answer</button>
</form>
`)
})
ourApp.post("/answer", function(req, res) {
if (req.body.skyColor.toUpperCase() == "BLUE") {
res.send(`
<p>Congrats, that is the correct answer.</p>
Back to homepage
`)
} else {
res.send(`
<p>Sorry, that is incorrect.</p>
Back to homepage
`)
}
})
ourApp.get("/answer", function(req, res) {
res.send("Are you lost there is nothing to see here.")
})
ourApp.listen(3000)
For the "/" route, the form you return should have action="/answer", not action="/"
Your other routes should stay the same, and pretty sure that should work.
ourApp.get("/", function(req, res) {
res.send(`
<form action='/answer' method='POST'>
<h2>What color is the sky on a clear and sunny day?</h2>
<input name="skyColor" autocomplete="off">
<button>Submit Answer</button>
</form>
`)
})
You are hitting wrong endpoint.
You should post to for example http://localhost:3000/answer.
And one more thing if you want to pass JSON data in body you need to use body-parser middleware.
https://www.npmjs.com/package/body-parser
Related
req.files keeps returning undefined. I've tried connect-multiparty, body-parser, and express-fileupload. How do I make it work using express-fileupload and not multer?
here's my frontend:
<form action="/api/upload" method="post">
<label for="imgHere">file:</label>
<input type="file" id="imgHere" name="imgHere"><br><br>
<input type="submit">
</form>
I've checked using inspect element network tab, its sending the image just fine.
here's my backend:
const express = require("express");
const app = express();
const fileUpload = require("express-fileupload")
app.use(fileUpload())
app.post('/api/upload', function(req, res) {
console.log(req.files) // logs undefined
res.send("uploaded.")
});
app.listen(80, function()
{
console.log("Server loaded.")
});
How do I fix this?
You need to specify proper enctype as form attribute as well, like this:
<form action="/api/upload" method="post" enctype="multipart/form-data">
<label for="imgHere">file:</label>
<input type="file" id="imgHere" name="imgHere"><br><br>
<input type="submit">
</form>
I am trying to make a post request from a html form and cant figure out where im going wrong.
> <form action="/api" method="POST">
<label for="username">username or email address</label>
<input name="username" id="username" type="text">
<label for="password">password</label>
<input id="password"name="password" type="text">
<button >Log in</button>
</form>
here is my main javascript file for the html (not the server)
"use strict"
let options = {
headers:{
"Content-Type" : "application/json"
},
method: "POST",
}
// fetch("/api",options)
And here is my node js server
"use strict"
//Installing express
let express = require(`express`)
let app = express()
app.use(express.json())
//running the server
app.listen(3000,()=>{
console.log("server is running boi");
})
//Middleware to load the static content
app.use(express.static(`public`))
//Database stuff
let Datastore = require('nedb')
let db = new Datastore({ filename: 'database.db' });
db.loadDatabase()
db.insert({username:"sid", password:"westham"})
//Handler for any post requests made
app.post(`/api`,(req,res)=>{
console.log("request was made");
console.log(req.body);
})
Two Observations
No middleware found in your server.js file for handling form data,
use body-parser http://expressjs.com/en/resources/middleware/body-parser.html
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true });
In your html form, if you're not submitting form with JavaScript then mentiod button type as submit
<button type="submit" >Log in</button>
Im trying to figure out why my post Method won't insert the user made in the register form into my user array, and no array is logged in node. When the register button is clicked, the site is also not redirecting to the /login page. Im not looking for the exact solution maybe just a tip to help me on the right path.
(all libraries is required)
The POST method im using
const express = require('express')
const app = express()
const bcrypt = require('bcrypt');
// helps finding specifik path
const path = require('path')
const port = 3000
// users array
const users = [];
app.use(express.static('views'))
app.listen(port,()=>{
console.log("App is listening on port 3000")
});
// VIGTIGT: tilader at vi kan hente data fra forms via "Name" tagget i formen!
app.use(express.urlencoded({ extended: false }))
// req router fra .auth/user_auth
// Routing: We are mapping to a special respond, and responds a HTML filer
app.get('/contact',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/contact.html'))
})
app.get('/login',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/login.html'))
})
app.get('/register',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/register.html'))
})
app.get('/home',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/home.html'))
})
app.get('/portfolio',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/portfolio.html'))
})
app.get('/adminpage', (req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/adminpage.html'))
})
// post metoder fra form
app.post('/register', async (req, res)=>{
try{
const hashedPassword = await bcrypt.hash(req.body.password, 10)
users.push({
id: Date.now().toString(),
name: req.body.username,
email: req.body.email,
password: hashedPassword
})
res.redirect('/login')
} catch{
res.redirect('/register')
}
console.log(users)
})
form im using
<form>
<div class="container">
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<label for="username"><b>Username</b></label>
<input type="text" placeholder="Enter username" name="username" required>
<label for="email"><b>Email</b></label>
<input type="text" placeholder="Enter Email" name="email" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password" required>
<hr>
<p>By creating an account you agree to our Terms & Privacy.</p>
<button href="/login" type="submit" class="registerbtn">Register</button>
</div>
<div class="container signin">
<p>Already have an account? Sign in.</p>
</div>
</form>
Firstly, you need to specify a method and an action to determine where the data is being sent to:
<form action="/register" method="POST">
</form>
Secondly, you are not parsing the incoming data when it is received by your server. The req.bodysyntax implies that the data is received as an object/JSON, but I don't see anything in your code that indicates you are doing this.
You can use one of a number of packages to do this for you, and Express has built-in middleware for this purpose. I'd recommend the body-parser package.
const bodyParser = require('body-parser');
app.use(express.json())
app.use(bodyParser.urlencoded({ extended: true }))
Worth adding a temporary console.log(req.body) to your function too just to check form data is being received as intended.
I think I'm lacking some understanding of these fundamental concepts (I've read a decent amount of resources and examples) of how these functions work server-side and how the html interacts with them. I was writing methods earlier today and communicating between the server and html perfectly, manipulating an array I had stored locally on the server file. For reference I'll show you how I was doing it.
jQuery script in html file:
$.post("/deck", { name: "Angel of Fury", power: 666 }, function(){
});
server file:
var express = require('express'),
app = express(),
db = require('./db'),
bodyParser = require('body-parser'),
controller = require('./controller');
//add body parser middleware
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
//Serves static pages
app.use(express.static(__dirname + ('/')));
//loads the html page
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
var server = app.listen(3000, function () {
var host = server.address().address;
host = (host === '::' ? 'localhost' : host);
var port = server.address().port;
console.log('listening at http://%s:%s', host, port);
});
var deck = [ ];
app.get('/deck', function(req, res) {
res.send(deck);
});
app.post('/deck', function(req, res) {
console.log(req.body);
var card = req.body;
deck.push(card);
res.send(deck);
});
Given this code I could navigate to "localhost:3000/deck and any changes I made were stored in the array and displayed at this address. Simple enough. I've taken that a step farther and implemented a database, mySQL and have successfully written methods for insertion, select, delete, etc..
<script>
$("submit").on("click", function(){
$.post("/users", { name: username.value, password: psw.value, email: email.value}, function(){
console.log("post successful..");
});
});
</script>
<body>
<form>
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="password" name="psw"><br>
email:<br>
<input type="text" name="email"><br>
<input type="submit" value="Submit">
</form>
</body>
I added the above form jquery script to the html page. And attempted to add the server functions below.
app.get('/users', function (req, res) {
});
app.post('/users', function (req, res) {
console.log(req.body);
});
I thought that this would allow me to use the req.body object on submission of the form. Please correct me if I'm going about this the wrong way, I would be grateful for any help/tips.
You can do two things:
Use event.preventDefault() to stop the form submission.
Change the button type to button instead.
As you have not prevented the form to submit so, whenever you click the submit button it submits the form and it makes a default get request if method attribute to post is not been provided.
$("submit").on("click", function(ev){
ev.preventDefault(); // <-------- HERE
$.post("/users", { name: username.value, password: psw.value, email: email.value}, function(){
console.log("post successful..");
});
});
Or make a small change at your markup:
<input type="button"....../>
In the form.
As per your latest comment, add a class/id attribute to the button and change the selector:
<input type="submit" id="submit"...../>
Now in js you have to use this:
$("#submit") // <---- notice the # which denotes the ID selector in jQuery.
So basically, I have a form and I cannot fetch data typed into it.(I'm using angular and node.js)
req.body
req.params are both empty
My html form :
<form ng-submit="sendTradelink()">
<md-input-container class="md-accent">
<label>Enter your tradelink</label>
<input ng-model="tradelink">
</md-input-container>
<md-button type="submit" class="md-raised md-accent">Send</md-button>
</form>
Controller :
$scope.sendTradelink = function () {
Auth.send()
.success(function (res) {
$location.path('/');
});
}
Service :
authFactory.send = function (tradelink) {
return $http.post($api.url + 'tradelink', {tradelink: tradelink});
};
Server side file where I want to work with data inserted into form:
api.post('/tradelink', function(req, res){
console.log(req.user.id);
console.log(req.params);
console.log(req.body);
res.json({
success: true,
message: 'tradelink received'
})
});
logs for controlling, empty every time.
As mentioned in comments, Express does not parse the body. POST requests are much more complex that GET ones, so the parser lies in a separate package, body-parser:
npm install --save body-parser
// server.js
api.use(bodyParser.urlencoded({
extended: true
}));
api.post('/tradelink', function(req, res) {
console.log(req.body.tradelink);
});
#Amadan answer is right. You also need to update the controller:
Auth.send($scope.tradelink)