I'm trying to do the most basic POST request in express but my req.body keeps returning undefined, I've googled similar issues but I can't find the solution that would work for me.
The form in HTML:
<form method="POST" class="vote">
<input type="text" name="test">
<button type="submit">TEST VOTE</button>
</form>
and in my post.js file
const express = require('express');
const app = express();
app.use(express.urlencoded({
extended: true
}));
app.post('/test', function (req, res) {
console.log('post to /test');
var data = req.body.test;
console.log(data);
What am I doing wrong here?
Try using body-parser node module which will parse the post data and append it on request object so that you can access it.
body-parser extract the entire body portion of an incoming request stream and exposes it on request.body.
const express = require('express');
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/test', function (req, res) {
console.log('post to /test');
var data = req.body;
console.log(data);
//rest of the code
}
Actually you didn't set the "action" field in your "form" tag.
You have to set your action field to
action= "/test"
Essentially, what I have is a form where a user will upload a CSV file.
<form action="/upload" method="POST" enctype="multipart/form-data">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile" name="file" required>
<label class="custom-file-label" for="customFile">Choose file</label>
</div>
<input type="submit" class="btn btn-primary btn-block">
</form>
FYI: I'm using getbootstrap.com as my style sheet.
Now, the form sends a POST request to /upload which is where my node.js code is. What I need is for the server to parse this CSV file and extract the data. I've got no idea what to do as all the different NPM packages such as Multer are using a system where the save the file locally and then parse it.
Edit: Forgot to mention this, but temporary local CSV hosting is not an option.
I need the client to upload server to process it and push to a DB, can't save the file locally anywhere.
Edit 2: I've used multer and the memory processing option and have gotten the following.
const express = require("express");
const app = express();
var bodyParser = require("body-parser");
var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({ storage: storage });
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.get("/", function(req, res) {
response.sendFile(__dirname + "/views/index.html");
});
app.post("/upload", upload.single('file'), async (req, res) => {
res.send(req.file)
});
const listener = app.listen(process.env.PORT, function() {
console.log("Your app is listening on port " + listener.address().port);
});
Now once I upload the file, I'm getting the following response (this is what req.file is).
{"fieldname":"file","originalname":"tech.csv","encoding":"7bit","mimetype":"application/octet-stream","buffer":{"type":"Buffer","data":[67,76,65,83,83,32,73,68,44,84,69,67,72,32,35,44,70,73,82,83,84,32,78,65,77,69,44,76,65,83,84,32,78,65,77,69,13,10,54,79,44,54,79,48,49,44,65,110,105,115,104,44,65,110,110,101]},"size":56}
So It's pretty clear that our data happens to be
67,76,65,83,83,32,73,68,44,84,69,67,72,32,35,44,70,73,82,83,84,32,78,65,77,69,44,76,65,83,84,32,78,65,77,69,13,10,54,79,44,54,79,48,49,44,65,110,105,115,104,44,65,110,110,101
but how do I process that? The csv file data was
CLASS ID,TECH #,FIRST NAME,LAST NAME
6O,6O01,Anish,Anne
So how do I go from the information provided in the buffer data attribute to the actual data?
All you have to use is Multer. Multer will return a buffer object which you can then make a string with the .toString() attribute.
Code:
const express = require("express");
const app = express();
var bodyParser = require("body-parser");
var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({ storage: storage });
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.get("/", function(request, response) {
response.sendFile(__dirname + "/views/index.html");
});
app.post("/upload", upload.single('file'), async (req, res) => {
var b = req.file["buffer"]
console.log(b.toString())
res.send(b.toString())
});
const listener = app.listen(process.env.PORT, function() {
console.log("Your app is listening on port " + listener.address().port);
});
I'm new to node and express, was trying to test some basics routes but getting a Type Error: Router.use() requires a middle ware function but got an object
This is what I have in app.js
const express = require('express');
const routes = require('./routes/api');
// set up express app
const app = express();
app.use('/api', routes);
//listen for request
app.listen(process.env.port || 4000, function(){
console.log('now listening for requests');
});
and in my api.js:
const express = require('express');
//store router object to a vairable to enable us use routes on api.js
const router = express.Router();
router.get('/ninja', function(req, res){
res.send('{type: "GET"}');
})
router.post('/ninja', function(req, res){
res.send({type: "POST"});
})
//to update an api, where id is a parameter.
router.put('/ninja/:id', function(req, res){
res.send({type: "PUT"});
})
//to delete an api
router.get('/ninja/:id', function(req, res){
res.send({type: "DELETE"});
})
module.exports = router;
I have tried exporting router on each file, none worked.
this is my first time when I'm setting up the server and need help. So my goal is to set up server by NodeJS and Expresss. Let's say we have an app with Admin and Users. When Admin clicks a button, it sends some data for the server, then Users can fetch the data.
So this is my server set up:
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port)
I can add some post method, let's say:
app.post('/', (req, res) => ....);
So I can prepare server reaction for listening the POST method, but I have no idea how to send some data from my app by clicking an button (I mean calling this post method). I've watched a bunch of tutorials and haven't seen any real-world exercises.
To receive the POST parameters, you need the body-parser module, which you can include in your app.js like this,
var bodyParser = require('body-parser');
app.use(bodyParser.json());
And here is how you can receive your form fields which are being sent through the POST method,
app.post('/', function(req, res) {
var someField1 = req.body.some_form_field;
var someField1 = req.body.form_field1;
});
Hope this helps!
On your express server
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post("/", (req,res) => {
res.send("Hello");
});
On your webpage/app, You can use axios.
Lets say your express server running with localhost and port 4000.
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var instance = axios.create({
baseURL: "http://localhost:4000" //use your express server's url(address) and port here
});
function onclick(){
instance.post("/").then( response => {
//response.data will have received data
}
}
</script>
You can use this function and call it on your button click
You can simply use jquery in your HTML page like this to call your api:
$("button").click(function(){
$.post("/", function(data, status){
alert("Data: " + data + "\nStatus: " + status);
});
});
And Send data from your api:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/', function(req, res) {
var obj = {};
obj.name="hello";
obj.lname="world"
res.json(obj);
});
Example:
HTML:
Your form elements should have name (it is mandatory) to access these in post body request.
<form method="post" action="/">
<input type="text" name="Name" />
<br>
<input type="text" name="Telephone" />
<br>
<input type="submit" />
</form>
app.js
const express = require('express')
const app = express()
const port = 3000
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/', (req, res) => {
name = req.body.Name;
telephone = req.body.Telephone;
res.render('somefolder/index', {
name: name,
telephone: telephone,
});
// Above code is for reference if you want to load another page after post complete and get posted values in this page too.
res.end();
});
I've tried using the expressjs csurf example from https://github.com/expressjs/csurf When using the first example in the Readme, (using Ejs template language), the token validation works fine. When I try using the 'Ignoring Routes' example, on the 'GET /form' to 'POST /process' execution(just as I did in the first example), I get 'invalid token' on the 'POST /process'. The token is being passed to the form on the GET. Any ideas?
Is 'app.use(csrfProtection)' not working? (used in the non working example, if I remove the 'use(csrfP..' and use the methodology from the working example to use the csrf module, IE, passing 'csrfProtection' to the 'get' and 'post' methods, the second example works)
Works:
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
app.set('view engine', 'ejs')
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())
app.get('/form', csrfProtection, function(req, res) {
// pass the csrfToken to the view
var tkn = req.csrfToken()
console.log(tkn)
res.render('index', { csrfToken: tkn })
})
app.post('/process', parseForm, csrfProtection, function(req, res) {
res.send('data is being processed')
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
html/ejs:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
Favorite color: <input type="text" name="favoriteColor">
<button type="submit">Submit</button>
</form>
</body>
</html>
Does not work:
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
app.set('view engine', 'ejs')
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())
// create api router
var api = createApiRouter()
// mount api before csrf is appended to the app stack
app.use('/api', api)
// now add csrf, after the "/api" was mounted
app.use(csrfProtection)
app.get('/form', function(req, res) {
// pass the csrfToken to the view
var tkn = req.csrfToken()
console.log(tkn)
res.render('index', { csrfToken: tkn })
})
app.post('/process', parseForm, function(req, res) {
res.send('csrf was required to get here')
})
function createApiRouter() {
var router = new express.Router()
router.post('/getProfile', function(req, res) {
res.send('no csrf to get here')
})
return router
}
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app2 listening at http://%s:%s", host, port)
})
In your second example, you are not passing the csrfProtection middleware to the POST processing chain. It should be
app.post('/process', parseForm, csrfProtection, function(req, res) {
res.send('csrf was required to get here')
})