I have a react app front end posting data to my server(use express) deployed on Heroku. Code works well when both client and server running on localhost, but when it's on Heroku, the req.body always gets empty object {}.
Can anyone point out what's going wrong here? Thanks in advance :)
React code:
axios.post("/api", data, {headers: { "Content-Type": "application/json;charset=utf-8" }})
Express code:
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(
cors({origin: URL,credentials: true}));
app.post("/api", (req, res) => {const data = req.body; console.log(data);};
This run perfectly on my computer. The log and the response works just fine. Hope it helps. I think the problem could be you are sending a GET request instead of a POST request.
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors({origin: new URL('http://localhost:3000'), credentials: true})) // Add this 'new' keyword to URL
app.post("/api", (req, res) => {
const data = req.body
console.log(data)
res.send(data) // Added this to allow request to end
})
// Added this part to start the server listen.
const port = process.env.PORT || 3000
app.listen(port , () => {
console.log('Server is running on port '+3000)
})
Related
Okay so i just started building an api using Node. Normally, before i even start, i test it in the postman using dummy data to make sure all the routes are working fine but i never tested it on the browser until today. It brings out the dummy data all fine in the postman but when I put in the same route i used in the postman on the browser tab, it just brings out my custom error message "Route does not exist". Why is this happening?
This is my routes/auth.js
const express = require('express')
const router = express.Router()
const {upload} = require('../utils/multer')
const { register, login } = require('../controllers/auth')
router.post('/register', upload.single('picture'), register)
router.post('/login', login)
module.exports = router
This is my controllers/auth.js:
const register = async (req, res) => {
res.send('register')
}
const login = async (req, res) => {
res.send('login')
}
module.exports = {register, login}
This is my app.js:
require('dotenv').config()
require('express-async-errors');
const bodyParser = require('body-parser')
const cors = require('cors')
const multer = require('multer')
const helmet = require('helmet') //helps you secure your Express apps by setting various HTTP headers.
const morgan = require('morgan')
const path = require('path')
const express = require('express');
const app = express();
/* CONFIGURATIONS */
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(morgan("common"));
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(express.urlencoded({ limit: "30mb", extended: true }));
app.use("/assets", express.static(path.join(__dirname, "public/assets")));
//routers
const authRouter = require('./routes/auth')
// error handlers
const notFoundMiddleware = require('./middleware/not-found');
const errorHandlerMiddleware = require('./middleware/error-handler');
//middleware
app.use(express.json());
app.use(cors());
//routes
app.use('/api/v1/auth', authRouter)
//errors
app.use(notFoundMiddleware);
app.use(errorHandlerMiddleware);
//database
const connectDB = require('./db/connect');
const port = process.env.PORT || 5000;
const start = async () => {
try {
await connectDB(process.env.MONGO_URI);
app.listen(port, () =>
console.log(`Server is listening on port ${port}...`)
);
} catch (error) {
console.log(error);
}
};
start();
Please note that i do not understand what most of these configurations do, not very well anyways. i have tried to remove them though but the problem was still there.
I am assuming you are trying to access /login or /register route from browser search bar something like this http://host:port/login. With this browser will send GET /login request but /login is a POST method route that is the reason you are getting Route not found
When you send request from your browser then by default it will send GET request and your app is not handling GET requests.
You are handling POST requests for /register and /login routes.
my app is unhappy when I try to call my back from my angular client:
I checked the documentation but also checked several forums but I couldn't solve my issue.
I have first tried to setup a proxy on my client:
proxy.conf.json
{
"/api/*": {
"target": "http://localhost:3000",
"secure": false,
"logLevel": "info"
}
}
And then ran:
ng serve --proxy-config proxy.conf.json --verbose
I ensured that the proxy was initialized since i got this in my logs:
[webpack-dev-server] [HPM] Proxy created: /api -> http://localhost:3000
But I keep getting the same issue...
I tried few variations like adding "changeOrigin": true and even tried the pathRewrite but this is probably pointless
Then I tried to change the config of my node js server to resolve the conflict. My main js file looks like so:
const express = require('express');
const cors = require('cors');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const routes = require('./routes/routes');
const API_URL = "/api/v1";
app.use(express.json());
app.use(API_URL, routes);
app.use(cors());
var server = app.listen(3000, () => {
console.log(("Server started on PORT 3000"));
})
And in my routes files I got:
const express = require('express');
const router = express.Router();
module.exports = router;
router.get('/getNeedQuery/:query', async (req, res) => {
try{
//some processing
res.status(200).json(//some object);
}
catch(error){
res.status(500).json({message: error.message});
}
})
And unfortunately I still get the same issue.
But when I try to directly run the url in my browser, it works for both PORT 4200 and 3000...
SOLUTION
I have finally fixed my issue. Even tho I gave up on the original idea which was to use a proxy.
I have fixed the CORS issue directly in the backend. The solution is not easy to determine when you discover middleware for the first time like me. For any people new to middleware, keep in mind that the order of declarations is very important and you really have to know which order is correct. In my case I was setting up the CORS security bypass after configuring the routes so it was ignoring the CORS configuration.
Old order (wrong):
const express = require('express');
const cors = require('cors');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const routes = require('./routes/routes');
const API_URL = "/api/v1";
app.use(API_URL, routes);
app.use(cors());
New order (correct):
const express = require('express');
const cors = require('cors');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const routes = require('./routes/routes');
const API_URL = "/api/v1";
app.use(cors());
app.use(API_URL, routes);
I hope this can help some people :)
I have created this post API, when I am trying to call it from postman req.body is null always, but the same API is working fine on my friend's laptop.
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: true}));
const sayHi = (req, res) => {
res.send("Hi!");
};
app.get("/", sayHi);
app.post("/add", (req, res) => {
const { a, b } = req.body;
console.log(req.body)
res.send(`The sum is: ${a + b}`);
});
app.listen(5000, () => {
console.log(`Server is running on port 5000.`);
});
this is my postman request: https://i.stack.imgur.com/d6QAZ.png
update:- I tried the same on my other laptop and it is working fine. I don't know why this is not working in my work laptop.
Hey Once try this middleware and send a proper request from POSTMAN I think this will resolve your all issues..
const express = require("express");
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true}));
I got this error "Cannot GET /api/data"
it s working good on my local host , but when I upload it to server it show me this error,
this is a simple code for testing that also show me the same .
my index page
const express = require('express');
const bodyparser = require('body-parser');
const mysql = require('mysql');
const port = 4000;
const route = require('route');
const data = require('./routes/data.js');
const app = express();
app.use(bodyparser.json());
// parse application/x-www-form-urlencoded
app.use(bodyparser.urlencoded({ extended: false }));
// parse the raw data
app.use(bodyparser.raw());
// parse text
app.use(bodyparser.text());
app.use('/data', data);
app.listen(port, () => {
console.log("working");
});
/routes/data.js file
const express = require('express');
const router = express.Router();
const add = require('../classes/insert');
const bodyparser = require('body-parser');
var con = require('../Modules/connection');
const app = express();
app.use(bodyparser.json());
// parse application/x-www-form-urlencoded
app.use(bodyparser.urlencoded({ extended: false }));
// parse the raw data
app.use(bodyparser.raw());
// parse text
app.use(bodyparser.text());
app.get("/",(req, res)=>{
res.send("hello");
});
module.exports = router;
app.use('/data', data)
This will only work on /data route. If you want this work on /api/data, use the following snippet.
app.use('/api/data', data)
this error may be comming because of the file path. Try using __dirname in spite of ./ and also check your file structure.
Hope this works.
I built an index.js file which sends SMS based on body input while posting with Postman. The code is working and looks like this (I have hidden my apiKey and apiSecret for this preview)
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const Nexmo = require('nexmo');
const nexmo = new Nexmo({
apiKey: 'hidden.apiKey',
apiSecret: 'hidden.apiSecret'
});
app.post('/send', (req, res) => {
// Sending SMS via Nexmo
nexmo.message.sendSms(
'4542542445', req.body.toNumber, req.body.message, {type: 'unicode'},
(err, responseData) => {if (responseData) {console.log(responseData)}}
);
});
const server = app.listen(3000);
console.log("starting server")
It woks fine and I receive an SMS message when I run the file, and a post to the route using Postman.
I am trying to implement the same in my bigger project, where I have separate client and server folders representing my frontend and backend.
When I add the code to my app.js file, I run into Status code 404 not found error. Here is the code of my app.js:
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const morgan = require('morgan')
const {sequelize} = require('./models')
const config = require('./config/config')
const Nexmo = require('nexmo')
const app = express()
app.use(morgan('combined'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false}))
app.use(cors())
require('./routes')(app)
sequelize.sync()
.then(() => {
app.listen(config.port)
console.log(`Server started on port ${config.port}`)
})
const nexmo = new Nexmo({
apiKey: 'hidden.apiKey',
apiSecret: 'hidden.apiSecret'
}, {debug: true})
app.post('/send', (req, res) => {
// Sending SMS via Nexmo
nexmo.message.sendSms(
'4542542445', req.body.toNumber, req.body.message, {type: 'unicode'},
(err, responseData) => {if (responseData) {console.log(responseData)}}
);
});
I am asking for help to try figure out what is wrong and why it does not hit the route, instead returning status code 404.
I can share my github or we can talk on discord: soko#8667
I appreciate your thoughts and help.
Routes in express should be written :
let route = require('routes');
app.use('/', route);
I managed to make it work.
I was adding new route while my server was running.
I restarted my PC and ran server and client again and it seems work.