Express API not responding when deployed on AWS LightSail - node.js

I am working on an API based service that was made and tested locally first and then deployed on AWS LightSail Ubuntu 20.04 . For whatever reason the server is not responding, as hitting any routes is neither logging nor sending a response back. FYI I tried other clients like the chrome console, postman etc. This is a simplified version of the code that was tested as well.
const express = require("express");
const bodyParser = require("body-parser");
const cors = require('cors');
const app = express();
app.use(cors({ origin: true }));
app.get("/", (req,res)=>{
res.send({
"msg":"worked"
});
console.log("hit hit hit");
});
app.listen(3000,()=>{
console.log("server started at port 3000");
})

Related

Deploying from Local Host to Heroku (Axios Request setup)

I have a react & node.js app that passes data from a form on the client side to server side via an axios POST request and receives a response. I'm trying to set this up on Heroku. On my local system it works perfectly but I can't seem to get it functional on Heroku. It renders the react app but errors on the axios request when the form is submitted which returns error 500 at /api:
const response = await axios.post('/api', poem);
In my local system I was able to use:
const response = await axios.post('https://localhost:3001/api', poem);
... but obviously this won't work in Heroku. Locally the react app would run on https://localhost:3000/ and the server on https://localhost:3001/. All my research says it should work with just the '/api' because it will default to https://my-app.herokuapp.com/api but I get an internal server error at that https://my-app.herokuapp.com/api.
My server.js file looks like this:
// server.js
const PORT = process.env.PORT || 3001;
const express = require("express");
//const cors = require("cors");
const axios = require("axios");
const fetch = require('node-fetch');
const path = require('path');
require('dotenv').config();
const app = express();
app.use(express.static(__dirname + '/'));
if (process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
app.get('*', (req, res) => {
res.sendFile(path.join('build', 'index.html'));
});
}
And here is my file structure: file structure.

Why ECONNRESET error is coming in POSTMAN while making a NODEJS request

I have written a simple request response code in NODEJS but there is no response in return of the request is there .
The code for my app.js(Server file) is
const express = require('express');
const cors = require('cors')
const paymentroute = require('./routes/paymentRoutes');
const app = express();
app.use(cors);
app.use("/api",paymentroute);
app.listen(3100,()=>{
console.log(`listening to port 3100`);
})
The code for my req and res is
const express = require('express');
const router = express.Router();
// const { checkout } = require('../controllers/paymentController');
router.post("/checkout",(req,res) => {
console.log("this function is called ")
return res.json({success:"true"})
});
module.exports = router;
Even the console.log inside the res function is not working.
Just change app.use(cors); to app.use(cors());
const express = require('express');
const cors = require('cors');
const paymentroute = require('./routes/paymentRoutes');
const app = express();
app.use(cors());
app.use('/api', paymentroute);
app.listen(3100, () => {
console.log(`listening to port 3100`);
});
I think it is a connection-related issue often related to a networking issue caused by a Virtual Private Network (VPN) that in some cases is required by some API services or, in other cases, prevents you to reach an API service.
The issue seems to be a combo of having the no-cache header enabled and a request URL length over 64 characters. If the issue persists after doing this solution then try to upgrade to the latest version of Postman.

Express rest api working in postman and development, but not when deployed

I have a project with Vue frontend, Express backend and Mysql as database (using Sequelize as ORM)
In development, the frontend communicates with the backend API without any issues.
When backend deployed on heroku, i can get a valid response when i use postman to query the endpoints
but when i try to do the same from the frontend running on localhost:8080, i get a blocked error as shown in the screenshot
below is my server.js (express startup code) that works when hosted on localhost:5000 and can communicate with the frontend on localhost:8080 but when backend is deployed to heroku, also working through postman, the fontend can't access the API on heroku because it gets blocked
I dont know if this is a CORS issue as the error says nothing about CORS.
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
//routes
const apiRouter = require('./routes/apiRouter');
app.use('/api', apiRouter);
/* -------------------------
Middlewares
------------------------
*/
app.use(cookieParser());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(passport.initialize());
app.use(morgan('dev'));
/* Port and start up */
const port = process.env.PORT || 5000;
app.listen(port);
The axios timeout was too short to work in production.
it was set to 50ms. Just had to increase it to 5s using interceptors
//from api.js
import axios from 'axios';
import store from '../store/store';
const token = store.getters.GET_WEBTOKEN;
export default axios.create({
baseURL: store.state.apiURL,
headers: {
Authorization: token,
},
});
//in main.js
import api from './service/api';
Vue.prototype.$http = api;
api.defaults.timeout = 1000 * 5; //I changed this
Now i solved the issue, unto other oones

CORS in node blocks POSTMAN to get data?

I'm using POSTMAN dev tool to test this API :
http://localhost:3000/users
and I have this express.js script :
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");
const mongoConfig = require("./config/mongodb.config");
var bodyParser = require("body-parser");
// Routers
const userRouter = require("./core/user/user.route");
const app = express();
const port = process.env.PORT || 3000;
const URI = mongoConfig.mongoURI;
const connectionOptions = mongoConfig.connectionOption;
// Connect Mongo Atlas database
mongoose
.connect(URI, connectionOptions)
.then(() => {
console.log("Connection is established successfully ...");
})
.catch((err) => {
console.error(err);
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.json());
app.use(cors);
app.use("/users", userRouter);
app.listen(port, () => {
console.log("The server is running on port", `${port}`);
});
The problem is when I remove CORS :
// app.use(cors);
POSTMAN can get data but when I add CORS it blocks and returns this stack trace :
Could not get any response
There was an error connecting to http://localhost:3000/users.
Why this might have happened:
The server couldn't send a response:
Ensure that the backend is working properly
Self-signed SSL certificates are being blocked:
Fix this by turning off 'SSL certificate verification' in Settings > General
Proxy configured incorrectly
Ensure that proxy is configured correctly in Settings > Proxy
Request timeout:
Change request timeout in Settings > General
As far as I know, POSTMAN is dev tool and CORS is related only with a browser but I did not understand the reason behind it.
After debugging my server.js I found the bug was inside my server and it's not related to POSTMAN.
The problem is using cors before user using my routers will block the server ( unlimited looping ).
So when I changed this code :
app.use(cors);
app.use(express.json());
app.use("/users", userRouter);
To
app.use("/users", userRouter);
app.use(cors);
app.use(express.json());
The issue is solved but I did not understand why and what happens exactly inside the server.

Allowing CORS in NodeJS

I defined my Express js app:
const express = require('express')
var history = require('connect-history-api-fallback');
const path = require('path')
const http = require('http')
const socketio = require('socket.io')
require('./db/mongoose')
const userRouter = require('./routers/user')
const publicDirPath = path.join(__dirname, '../public')
const app = express()
app.use(express.static(publicDirPath))
app.use(history({
index: '../public/index.html'
}))
app.use(express.static(publicDirPath))
app.use(express.json())
app.use(userRouter)
const server = http.createServer(app)
const io = socketio(server)
io.on('connection', socket => {
console.log('New WebSocket connection')
socket.on('join', () => {
socket.emit('message', 'Welcome to the app')
})
})
module.exports = server
Then I use it my index.js file:
const app = require('./app')
const port = process.env.PORT
app.listen(port, () => {
console.log(`Server is up on port ${port}`)
})
When I run the app and send requests from the same port - everything works just fine. But when I try to send requests from different localhost port, ie. 8080, I'm getting cross origin error.
I tried to install cors package and use it as follows:
const cors = require('cors')
app.options('*', cors())
app.use(cors());
And got the same result.
I tried to pass configuration to cors:
app.use(cors({
origin: 'http://localhost:8080'
}));
And still got the same result.
What am I doing wrong and how can I make it work?
When your frontend app tries to make the request to the express server,
The express server is blocking that request because the source of the request (i.e. frontend server) is unknown to the express server
As the request that you are trying to make it out of the domain of the express server. this is the reason where you have to tell the server please accept the request from this origin a.k.a IP Address
and you can achieve the via cors
Let's take a minute to explain what "origin" is in simple words.
When a user browses to a website, he uses an address.
Normally that address is a domain, but when we run our tests we mostly work with local IPs.
For CORS, this doesn't matter. Once you enable Allow-Origins, the server looks at the address the user used to reach the website, and defines it as the "origin" of the request.
Obviously, on a deeper level, everything comes down to IP addresses. But when it comes to CORS, it's more of a high-level security method. It's helps preventing Cross-Site Request-Forgeries for example.
In conclusion, in order for CORS to work,
make sure you allowed the address which the user is using to access the HTTP service.
So, if you're serving a VUE app that's working on http://localhost:8080, and from it calling to an HTTP service on http://localhost:5555, you'll need to do this on the said HTTP service:
app.use(cors({
origin: 'http://localhost:8080'
}));

Resources