How to catch POST request on back-end? - javascript

<!doctype html>
<head>
</head>
<body>
<script>
const Http = new XMLHttpRequest();
const url='http://localhost:4550/users';
Http.open("POST", url);
Http.send("hey");
Http.onreadystatechange = (e) => {
console.log(Http.responseText)
}
</script>
</body>
</html>
//user.js
var express = require('express');
var router = express.Router();
var array = [];
/* GET users listing. */
router.get('/', (req, res, next) => {
res.send('respond with a resource1');
});
router.post('/', (req, res, next) => {
res.send('respond with a resource2');
});
module.exports = router;
//app.js
const express = require('express')
const app = express();
app.get('/',(req,res)=> {
console.log('lior');
res.send('api running 2')});
app.use('/users',require('./routes/users'))
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
const PORT = process.env.PORT || 4550;
app.listen(PORT,()=> console.log('server started on port ${PORT}'));
I am new with connecting client and server side, and it might be why I couldn't find an answer for my question. Is a simple question.
As you can see I want to send "hey" from the client to the server(user.js). However I don't know how does I catch the response on the server side.
I know that a "hey" or neither the code make much sense, but is just an example to make things simple, I just wondering how does the server side could catch and handle the data.
Thanks in advance!

When you post data, specify how you are encoding it. It's generally best to use a standard encoding method rather than POSTing plain text. (Also don't start variable names with capital letters unless they are constructor functions)
const http = new XMLHttpRequest();
const url = 'http://localhost:4550/users';
const data = JSON.stringify({ value: "hey" });
http.open("POST", url);
http.setRequestHeader("Content-Type", "application/json");
http.send(data);
http.onreadystatechange = (e) => {
console.log(http.responseText)
}
Then in your server side code, use a body parser to decode the data.
Since you are using an absolute URL in the request, it seems likely that you are making a cross-origin request so you also need to grant permission using CORS.
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const app = express()
const port = 4550
const jsonParser = bodyParser.json()
const corsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200
};
const corsMiddleware = cors(corsOptions)
app.get('/', (req, res) => res.send('Hello World!'))
app.get('/users', (req, res, next) => {
res.send('respond with a resource1');
});
app.options("/users", corsMiddleware)
app.post('/users', corsMiddleware, jsonParser, (req, res, next) => {
// data is in `req.body` (which will have a `value` property because the object on the client does)
res.send('respond with a resource2');
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
(The above is untested and may have minor errors in it)

Please send serialized data as below:
const http = new XMLHttpRequest();
const url = 'http://localhost:4550/users';
const data = JSON.stringify("hey");
http.open("POST", url);
http.setRequestHeader("Content-Type", "application/json");
http.send(data);
You need to use bodyParser package
npm install body-parser
const bodyParser = require("body-parser");
and before setting up routes use it as below :
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
Don't forget to allow the headers declaration as below :
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST"
);
next();
});
and now you can read your data as below
router.post('/users', (req, res, next) => {
console.log(req.body);
});

Related

Cannot POST to Express router (404 error)

I cannot fetch POST requests to my Express router. I have many GET requests which work fine, but this is my first POST request and it is not working.
My frontend code looks like this:
export async function postHamster(name, age) {
try {
await fetch('/hamsters/api/new-hamster',
{
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: name,
age: age
})
})
console.log("postHamster has run") //LOGGED
}
catch (e) {
console.error(e)
}
}
The response will always be:
fetchData.js:38 POST http://localhost:3000/hamsters/api/new-hamster 404 (Not Found)
I have triple-checked the path and it cannot be in error. The backend path is "router.get('api/new-hamster', async (req, res)..." in the file 'hamsters.js'.
I have also put the backend function at the very top of its file, to ensure that it is not overrruled by any other function in the file.
This is my server.js:
// THIS FIRST FUNCTION I JUST COPIED FROM A SOLUTION BUT IT DOES NOT SEEM TO HELP
// routes/index.js
module.exports = (express) => {
// Create express Router
var router = express.Router();
// add routes
server.route('/hamsters/api/new-hamster')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send('You sent: sdadad to Express');
});
return router;
}
const express = require('express');
const server = express();
const serverPort = process.env.PORT || 1234;
server.use(express.static(__dirname + '/../build'))
let data = require('./data.json')
const { Router } = require('express');
let router = new Router();
//USE BODY-PARSER BEFORE REGISTERING ROUTES!
const bodyParser = require('body-parser')
server.use(bodyParser.urlencoded({ extended: true }));
server.use(bodyParser.json())
server.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// ROUTES
const hamstersRoute = require('./routes/hamsters');
const chartsRoute = require('./routes/charts')
const gamesRoute = require('./routes/games')
const statsRoute = require('./routes/stats')
const imagesRoute = require('./routes/images')
const uploadRoute = require('./routes/upload')
server.use('/assets', express.static("assets"))
server.use(express.static('public'))
server.use('/hamsters', hamstersRoute)
server.use('/charts', chartsRoute)
server.use('/games', gamesRoute)
server.use('/stats', statsRoute)
server.use('/images', imagesRoute)
server.use('/upload', uploadRoute)
server.listen(serverPort, () => {
console.log(`Server is up n running on port ${serverPort}!`)
})
module.exports = data;
I have looked at these threads:
Cannot GET/POST with express Router()
Express.js routers post request returns 404
Express: router cannot read POST request
Have you checked the url you're trying to post to in the network tab in the console? I think you need to add a / before api in the backend route: router.get('/api/new-hamster', async (req, res)...".
You have this:
server.use(bodyParser.urlencoded({ extended: true }));
Instead of this:
server.use(bodyParser.urlencoded({ extended: false }));

Socket.io GET/POST 404

I was searching for a similiar issue, but I still can't fix this problem. I'm working on a chat app in ReactJs, Node/Express, Mongoose and Socket.io. Everything works, db is working, server is running, so now I want to add socket. I'm trying to connect client side with server, but I get error (about every 2/3sec) POST/GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=N5PeKkf 404 (Not Found).
React:
const host = 'http:localhost:5000/api/rooms'
const [endpoint, setEndpoint] = useState('')
const {width,mobileWidth} = props;
useEffect(()=>{
setEndpoint(`${host}${props.location.pathname}`);
socket = io(endpoint);
const roomId = props.location.pathname.slice(1,props.location.pathname.length);
socket.emit('join', {roomId})
},[endpoint])
Node:
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const socketIo = require("socket.io");
const http = require("http");
const HttpError = require('./models/http-error');
const roomsRouter = require('./routes/rooms-routes');
const usersRouter = require('./routes/users-routes');
const app = express();
mongoose
.connect(
`mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASSWORD}#cluster0-lnoai.mongodb.net/${process.env.DB_NAME}?retryWrites=true&w=majority`
)
.then(() => {
app.listen(process.env.PORT || 5000);
})
.catch(err => {
console.log(err);
});
const server = http.createServer(app);
const io = socketIo(server);
app.use(bodyParser.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE');
next();
});
io.on('connection',(socket)=>{
console.log('connected');
})
app.use('/api/rooms', roomsRouter);
app.use('/api/users', usersRouter);
app.use((req, res, next) => {
throw new HttpError('Route not found.', 404);
});
app.use((error, req, res, next) => {
if (res.headerSent) {
return next(error);
}
res.status(error.code || 500).json({
message: error.message || 'An uknown error occurres!',
errorCode: error.code || 500
});
});

Using Express JS to make API external CALL (avoiding cors problem)

I am trying to make API calls using express js to get some data and then use them for my school project!
I have heard that I can install an extension or something like that on my browser but that will only work on my pc.
So I am trying to create my own proxy using Express JS.
Do I need to write something else on I app.get('/') or is it okay with a slash.
Thanks in advance!
const express = require('express');
const request = require('request');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
let key1 = '8151a53b2c1d4c3db2df'
let url ='http://api.sl.se/api2/realtimedeparturesv4.json?key='+key1+'&siteid=9192&timewindow=5'
app.get('/', (req, res) => {
request( { url: url},
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: err.message });
}
res.json(JSON.parse(body));
console.log(body);
} )
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));```
Use the cors package like this
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
if you want to enable it for a single route :
app.get('/', cors(), (req, res) => {
});

Exporting Objects in NodeJS for API

I'm trying to write a RESTful API in NodeJS that connects to a MySQL database. I have multiple files that handle routes:
I'm using the "mysql" package from www.npmjs.com. In app.js I create a connection object for the database but then want to use that object in both books.js and entries.js. I need to use the connection object to send queries to the database and I plan to do that in the routes files (books.js, etc.). What is the proper way to export and import that object? I'm new to NodeJS. Also, app.js is already exporting "app".
app.js:
const express = require('express');
const app = express();
const morgan = require('morgan');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const bookRoutes = require('./api/routes/books');
const entryRoutes = require('./api/routes/entries');
const connection = mysql.createConnection({
host: 'localhost',
user: 'rlreader',
password: process.env.MYSQL_DB_PW,
database: 'books'
});
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'GET');
return res.status(200).json({});
}
next();
});
// Routes which should handle requests
app.use('/books', bookRoutes);
app.use('/entries', entryRoutes);
app.use((req, res, next) => { //request, response, next
const error = new Error('Not found');
error.status = 404;
next(error);
});
app.use((error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: {
message: error.message
}
});
});
module.exports = app;
books.js:
const express = require('express');
const router = express.Router();
const axios = require('axios');
router.get('/', (req, res, next) => {
axios.get('/').then(docs => {
res.status(200).json({
"hello": "hi"
})
}).catch(err => {
res.status(500).json({
error: err
});
})
});
module.exports = router;
GrafiCode had the answer to this one. I made a separate file called db.js
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'rlreader',
password: process.env.MYSQL_DB_PW,
database: 'books'
});
module.exports = connection;
Then, in books.js I added:
const con = require('../../db');
Then I was able to use the .query() from the mysql component in multiple files.

Express can't reach route

I have the following file: (auth.js)
module.exports = function (express, mongoose, router) {
router.route('/setup')
.get(function (req, res) {
var salt = bcrypt.genSaltSync(10);
var hashed = bcrypt.hashSync(req.query.password, salt);
// create a sample user
mongoose.models.playlist.create({username: 'Hieratic', password: hashed}, function (err, item) {
if (err) throw err;
console.log('User saved successfully');
res.json({ success: true });
});
});
return router;
};
And the current server file: (server.js)
"use strict";
var url = require('url');
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var crypto = require('crypto');
//npm install request
var request = require('request');
var config = require('./config/access.json');
var admin = require("firebase-admin");
var fireBaseConfig = require('./config/firebase.config.json');
var mongoose = require('mongoose');
var MongoClient = require('mongodb').MongoClient;
var mongodbConfig = require('./config/database.json');
var exec = require('child-process-promise').exec;
var app = express();
/**
* Schemas
*/
var UserModel = require('./schemas/user.schema.js')(mongoose);
var PlayListModel = require('./schemas/playlist.schema.js')(mongoose);
app.use(function (req, res, next) {
// CORS headers
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, x-access-token, Cache-Control, Pragma"
);
next();
});
var router = express.Router();
app.use(bodyParser.json({limit: '4mb'}));
app.use(bodyParser.urlencoded({
extended: true,
limit: '4mb'
}));
if (mongodbConfig.username && mongodbConfig.password) {
mongoose.connect(`mongodb://${mongodbConfig.username}:${mongodbConfig.password}#${mongodbConfig.host}:${mongodbConfig.port}/${mongodbConfig.database}`);
}
else {
mongoose.connect(`mongodb://${mongodbConfig.host}:${mongodbConfig.port}/${mongodbConfig.database}`);
}
process.on('disconnect', function () {
// If mongodb connection is not terminated child process never dies
mongoose.disconnect();
});
require('./auth.js')(express, mongoose, router);
var port = 51000;
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
When i attempt to access the /setup route it does hit the server however it throws an html page:
(http://localhost:51000/setup):
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /setup</pre>
</body>
Can anyone see what ive done wrong?
You have created router, but not registered it as a middleware:
var router = express.Router();
require('./auth.js')(express, mongoose, router);
app.use(router);
Refer to Cannot GET / Nodejs Error
You have no route set up.
Serve your page like this:
app.get('/', function (req, res) {
res.render('index', {});
});

Categories