Send post request from one web server to another - node.js

I'm trying to send a post request from one server to another
Say I've got two servers (on node.js) running on localhost:3000 and localhost:4000, now I'm trying to send a post request from 3000 to 4000.
I've tried this
app.post('/some_routes', (req, res) => { console.log('request recieved')} )
// on recieving side, ie. localhost:4000
<form action="localhost:4000/some_routes" method="POST">
<input type="submit" value="Submit">
<form>
<!-- on sending side, ie. localhost:3000 >
But that doesn't seem to work. Any suggestions?
Also please add both client and server side snippets.

Have a look at axios
You can then do a post like this
axios.post('/some_routes', {
some: 'data',
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

I have the same scenario and it is working, as shown below
On Local Host 4000:
router.post('/some_routes', async function(req, res) { console.log('request recieved')} );
On Local Host 3000:
<form name="submitForm" method="POST" action="http://localhost:4000/some_routes/">
<input type="submit" value="Submit">
Click on the link
</form>
The problem that I face is that it is not working on different servers.

Related

User session does not get destroyed Nodejs

Guys I have this logout button on my react app that executes the LogoutSession() function that goes like this:
<span onClick={LogoutSession} className="btn btn-light rounded-pill text-primary py-2
px-4 ms-lg-5">Log Out</span>
And this is the function:
const LogoutSession = (e) =>{
e.preventDefault();
Axios.get('http://localhost:3001/logout')
}
And in my server side (nodejs) I have this route:
router.get('/logout', async(req,res) => {
req.session.destroy();
console.log(req.session)
});
And I guess the problem is with the LogoutSession function cause I didn't know how to use Axios well to make that route work, is there any parameters that I'm missing or something I did wrong in the client side
Setting the session to null will also work:
req.session = null;

Heroku server api call (localhost) not working

I'm on the final stretch of my web app, and I'm trying to deploy it with Heroku. The backend is very simple, and just uses express and while I was coding, a simple localhost server to create a token on login (localhost:8080/login). Unfortunately, on Heroku the login and token generation will not work unless I'm using my computer and I've ran node server.js already in my terminal. Also not sure if this context is needed, but locally, my react app is launched at localhost:3000 while the server is localhost:8080/login. I've heard that I should change them both to be the same localhost with some slight changes to the url, but nothing's worked so far. What changes do I need to make to the relevant code below so that Heroku will use its own server for the api call?
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.use('/login', (req, res) => {
res.send({
token: 'test123' // simple test send token
});
});
app.listen(8080, () => console.log('API is running on http://localhost:8080/login'));
Server.js (I have to run npm start, Ctrl+C, then node server.js in order to login properly)
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import './Login.css';
async function loginUser(credentials) {
return fetch('http://localhost:8080/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
})
.then(data => data.json())
}
export default function Login({ setToken }) {
const [username, setUserName] = useState();
const [password, setPassword] = useState();
const handleSubmit = async e => {
e.preventDefault();
const token = await loginUser({
username,
password
});
setToken(token);
}
return(
<div className="login-wrapper">
<h1>Please Log In</h1>
<form onSubmit={handleSubmit}>
<label>
<p>Username</p>
<input type="text" onChange={e => setUserName(e.target.value)} />
</label>
<label>
<p>Password</p>
<input type="password" onChange={e => setPassword(e.target.value)} />
</label>
<div>
<button type="submit">Submit</button>
</div>
</form>
</div>
)
}
Login.propTypes = {
setToken: PropTypes.func.isRequired
};
Login component where token will be generated
This is due to your Heroku app's localhost is not pointing to your server application.
The most straight forward way to resolve this is to publish your server application on Heroku as well, then change your function loginUser to point to the URL to your server application's Heroku URL. You may later refactor the URL to refer to an environment variable so you have zero code change when developing locally and pushing to Heroku. This deploy guide will probably come in handy for you in this case.
If you do not intend to have publish your server application on Heroku due to any reason, you may also start your server on a local machine and expose it through ngrok, but you will need to refactor the fetch URL now as ngrok will have different URL every time you start it.

NodeJS (Express) - app.delete route not working

Working on understanding CRUD basics with setting up simple routes from my HTML5 doc to Postgres database. My GET and POST buttons are working but my DELETE is not deleting from my database. I realize the routes all look very similar (and tried renaming them to see if it would hit the callback function that is linked to the database, but it didn't work). Can anyone tell me why my HTML5 form is not working with my route to reach the database for DELETE? Thanks!
I will only include the code I'm referring to as I have all the other code working well. Starting with showing the crappy HTML first, then the index.js with the routes, and then the queries.js with the database queries. ( ////// seperate the documents where the code is pulled :) )
<h1>Let's DELETE ONE Human</h1>
<form action="/users/:id" method="delete">
ID:<input type="number" name="id">
<input type="submit" name="">
</form>
/////////////////////////////////////////////////////////////////
app.get('/', (request, response) => {
response.sendFile(path.join(__dirname + '/html/homepage.html'))
}, db.getUsers)
app.get('/newHuman.html', (request, response) => {
response.sendFile(path.join(__dirname + '/html/newHuman.html'))
})
app.get('/users', db.getUsers)
app.get('/users/:id', db.getUserById)
app.post('/users', db.createUser)
app.put('/users/:id', db.updateUser)
app.delete('/users/:id', db.deleteUser)
app.listen(port, () => {
console.log(`App running on port ${port}.`)
})
////////////////////////////////////////////////////////////////////////
const deleteUser = (request, response) => {
const id = parseInt(request.query.id)
pool.query('DELETE FROM users WHERE id = $1', [id], (error, results) => {
if (error) {
throw error
}
response.status(200).send(`User deleted with ID: ${id}`)
})
}
TL;DR
How can I send to the correct route (even with just POSTing twice) from my HTML when the app.delete and app.put have the exact same route? Tried renaming route, didn't work but I know you shouldn't have to rename for it to work. Here are routes:
app.put('/users/:id', db.updateUser)
app.delete('/users/:id', db.deleteUser)
HTML form method only supports GET and POST method.
Either you have to use GET or POST or you can use ajax or some library like request or axios to make the DELETE request.
For example, if you use axios, try the following code.
Ignore importing jQuery and axios, if you already imported them.
<!-- import jQuery -->
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"></script>
<!-- import axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<h1>Let's DELETE ONE Human</h1>
<form id='myFormId' action="/users/:id" method="delete">
ID:<input type="number" name="id" id='deleteId'>
<input type="submit" name="">
</form>
<script>
$( document ).ready(function() {
const myForm = $('#myFormId');
myForm.submit((event) => {
event.preventDefault();
const id = $('#deleteId').val();
const url = `/users/${id}`;
axios.delete(url)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
});
});
</script>
Another easier way of doing this is using a npm module called method-override.
In your main entry point file for your server, add the following lines:
const express = require('express');
const app = express();
const methodOverride = require('method-override');
app.use(methodOverride('_method'));
In your HTML form, you can now use PUT or DELETE requests easily:
For example:
<h1>Let's DELETE ONE Human</h1>
<form id='myFormId' action="/users/:id?_method=DELETE" method="delete">
ID:<input type="number" name="id" id='deleteId'>
<input type="submit" name="">
</form>
Notice the action attribute of the form, all you have to do now is add that simple line and you are done!

Redirecting to URL within a POST Request

I've been searching around but couldn't seem to find an answer to this...
I'm really new to NodeJS. I'm trying to write a server that will take the POST request when user try to login, then redirect to the home page using GET, and the home page will now display the username.
so if the url is home.html, on the page it says guest, if the url is home.html?username=adam then on the page it says adam
On my login.html, there's a form similar to this
<FORM ACTION="login.html" METHOD="POST">
<CENTER>
Username: <INPUT TYPE="text" ID="username" required=true><BR>
Password: <INPUT TYPE="password" ID="password" required=true><BR>
<INPUT TYPE="SUBMIT">
</CENTER>
</FORM>
On my server.js, I have the block trying to get the username and redirect
http.createServer(function (req, res) {
if(req.url == "login.html" && req.method == "POST")
{
req.on('data', function(chunk) {
var someData += chunk;
var username = //get from POST data
//attempt to redirect
res.writeHead(200, {"Location":"home,html?username=adam"});
res.end();
});
}
}
I was able to get the username and log it, but when I tried to redirect, the page came back blank, and the url still says login.html...
I'm not even sure if I'm doing it correctly, please help.
As you are new to nodejs please try to use REST API for communication instead of redirecting to other pages directly.
To retrieve the form data in server js you need to install body parser which is detailed here:
[https://github.com/expressjs/body-parser][1]
Then update your server js like below:
var app = require('express')();
var http = require('http').Server(app);
var bodyParser = require('body-parser')
app.use(bodyParser());
app.get('/login', function (req, res) {
res.sendfile('login.html');
});
app.get('/home', function (req, res) {
res.sendfile('home.html');
});
app.post('/login', function (req, res) {
console.log("Username:",req.body.username);
console.log("password:",req.body.password);//just for reference do not show anywhere
res.redirect('/home?username='+req.body.username);
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
And your login login.html will looks like this:
<FORM ACTION="/login" METHOD="POST">
<CENTER>
Username: <INPUT TYPE="text" name="username" ID="username" required=true><BR>
Password: <INPUT TYPE="password" name="password" ID="password" required=true><BR>
<INPUT TYPE="SUBMIT">
</CENTER>
</FORM>
Do necessary action on home page as now you are avail with username on url..hope this help..let me know if any doubts. Happy coding:)

Error while piping POST request using request library

I'm using request to communicate between two Sails applications. The concerned actions seem to get triggered but the form data shows undefined.
In app A:
The concerned form
<form action="/testreq" method="post" enctype="multipart/form-data">
<input name="name" type="text"><br/>
<input name="dp" type="file"><br/>
<input type="submit" value="Submit">
</form>
The concerned controller
testreq: function(req, res, next) {
console.log(req.param('name'));
var r = request.post('http://localhost:9999/upload');
req.pipe(r);
return r.pipe(res);
},
In app B:
The concerned controller
upload: function(req, res, next) {
var name = req.param('name');
console.log(name);// prints "undefined"
return res.json({ message: 'Some message' });
}
While the console.log should print the name sent from the form, it outputs undefined. Any idea where I'm going wrong?

Resources