CORS POST request blocked in EXPRESS & REACT on hosting & domain - node.js

I'm using express CORS module & react AXIOS on my host & domain.
I defined CORS() in my route middleware, and the GET request worked perfectly.
but for POST & PUT requests still, the Access-Control-Allow-Origin BLOCKED error displays.
ALSO I'm using webpack and dev server to proxy front end react
This is my express server.js file
const express = require("express");
const app = express();
const db = require("./config/db");
db.connect(() => {
console.log(`Postgres connected`);
});
// Middlewares
// CORS
const cors = require("cors");
app.use(cors(
{
origin: http://asia-sarmaye.ir
}));
// BodyParsing
var bodyParser = require("body-parser");
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// Router
app.use("/api", cors(), require("./routes/dum"));
// Listening
const port = 4000;
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
And this is REACT axios POST request
axios
.post(
"http://api.asia-sarmaye.ir/api/user",
{
headers: { "Access-Control-Allow-Origin": "*" }
},
data,
res => {
console.log(res.data);
}
)
any idea how to fix this?

You need to set proxy.
Hope below given link help you. It helped me too.
Enable CORS in my React App with Node.js backend

Related

Route does not exist on the browser but it works fine on the postman

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.

CORS preflight request error on angular app deployed on heroku with node express backend

I have deployed an angular app on heroku (with the frontends and backend separated in multiple heroku apps) for a project at school and I'm stuck on an issue with CORS preflight requests.
Everytime I send a request to the backend I get the following error
Access to XMLHttpRequest at 'https://playlist-manager-backend.herokuapp.com/user/authenticate' from origin 'https://playlist-manager-admin.herokuapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Here is the code of my server.js pushed on the backend app (playlist-manager-backend)
const express = require("express");
const { connect: dbconnect } = require("./src/db");
const { apiPort } = require("./src/config");
const routes = require("./src/routes");
const bodyParser = require("body-parser");
// Connect to the database
dbconnect();
// Create the server
const app = express();
// const cookieParser = require("cookie-parser");
// app.use(cookieParser());
app.use(bodyParser.json({ limit: "5mb" }));
// app.get("/", (req, res) => res.send("Hello World"));
const cors = require("cors");
/*let whitelist = ["https://playlist-manager-admin.herokuapp.com/","https://playlist- manager-user.herokuapp.com/"];*/
const corsOptions = {
origin: ["https://playlist-manager-admin.herokuapp.com/", "https://playlist-manager-user.herokuapp.com/"],
preflightContinue:false,
credentials: true
}
app.use(cors(corsOptions));
app.use("/", routes);
app.use(express.static("./adverts"));
app.listen(apiPort, () => {
console.log(`Server is listening on port ${apiPort}`);
});
The routes to the backend functions are defined using router in the routes.js file like this.
const express = require("express");
const router = express.Router();
const userRoute = require("../user/user.route");
const playlistRoute = require("../playlist/playlist.route");
const videoRoute = require("../video/video.route");
const annonceUploadRoute = require("../annoncesUpload/annoncesUpload.route");
const historyRoute = require("../history/history.route");
const advertiserRoute = require("../advertiser/advertiser.route");
router.use("/user", userRoute);
router.use("/playlist", playlistRoute);
router.use("/video", videoRoute);
router.use("/annoncesUpload", annonceUploadRoute);
router.use("/history", historyRoute);
router.use("/annonceur", advertiserRoute);
module.exports = router;
Here is an example of how routes are implemented :
router.post("/getById", async function(req, res) {
const request = {
_id: req.body._id,
};
const result = await bo.getById(request);
res.send(result);
});
The frontend sends a post request to the backend using a service implemented like this :
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
export interface BackendData {
success: string ;
data: any ;
}
#Injectable({
providedIn: 'root'
})
export class MessageService {
constructor(private http:HttpClient) { }
sendMessage(Url:string, data:any): Observable<BackendData> {
const serveur = environment.server + Url ;
return this.http.post<BackendData>(
serveur,
data,
{withCredentials: true}
);
}
}
I tried every solutions I saw online but I always got the same error or another error related to CORS policy.
I need help figuring out this behavior.
The app was working fine locally when I specified localhost with cors package like in the documentation.
Edit :
I removed slashes on the URL's and my server.js is like this :
const express = require("express");
const { connect: dbconnect } = require("./src/db");
const { apiPort } = require("./src/config");
const routes = require("./src/routes");
const bodyParser = require("body-parser");
// Connect to the database
dbconnect();
// Create the server
const app = express();
// const cookieParser = require("cookie-parser");
// app.use(cookieParser());
app.use(bodyParser.json({ limit: "5mb" }));
// app.get("/", (req, res) => res.send("Hello World"));
const cors = require("cors");
/*let whitelist = ["https://playlist-manager-admin.herokuapp.com/", "https://playlist-manager-user.herokuapp.com/"];*/
const corsOptions = {
origin: ["https://playlist-manager-admin.herokuapp.com", "https://playlist-manager-user.herokuapp.com"],
credentials: true
}
app.use(cors(corsOptions));
app.use("/", routes);
app.use(express.static("./adverts"));
app.listen(apiPort, () => {
console.log(`Server is listening on port ${apiPort}`);
});
This is the network tab after sending the request
This is the xhr request shown in the network tab
This is the preflight request in the network tab
Thanks to jubObs comments I managed to fix this. The source of the problem was that the backend server wasn't starting which was causing a 503 status. I forgot to add the file defining the credentials for the database connections which caused the backend to fail before adding the headers.
here is the new server.js code :
const express = require("express");
const { connect: dbconnect } = require("./src/db");
const { apiPort } = require("./src/config");
const routes = require("./src/routes");
const bodyParser = require("body-parser");
// Connect to the database
dbconnect();
// Create the server
const app = express();
// const cookieParser = require("cookie-parser");
// app.use(cookieParser());
app.use(bodyParser.json({ limit: "5mb" }));
// app.get("/", (req, res) => res.send("Hello World"));
const cors = require("cors");
/*let whitelist = ["https://playlist-manager-admin.herokuapp.com/", "https://playlist-manager-user.herokuapp.com/"];*/
const corsOptions = {
origin: ["https://playlist-manager-admin.herokuapp.com", "https://playlist-manager-user.herokuapp.com"],
credentials: true
}
app.use(cors(corsOptions));
app.use("/", routes);
app.use(express.static("./adverts"));
app.listen(apiPort, () => {
console.log(`Server is listening on port ${apiPort}`);
});
The database connection was using dotenv and the .env file that was defining the database credentials wasn't present in the main branch so I pushed it.
To figure this out I checked the application logs on heroku which are in "more" and "view logs".

Unable to fetch request in react(client-side) and express server

Iam trying to fetch request from backend in form of post and it seems like my backend and frontend are not serving together
React SignIn code(Client-side)
onSubmitSignIn=()=>{
fetch('http://localhost:3000/signin',{
method:"POST",
headers:{'Content-Type':'application/json'},
body: JSON.stringify({
email:this.state.signInEmail,
password:this.state.signInPassword
})
})
.then(response=>response.json())
.then(data=>{
if(data==='success'){
this.props.OnRouteChange('home');
}
})
}
Server side
const express = require('express');
const bodyparser= require('body-parser');
const cors = require('cors');
const app=express();
app.use(bodyparser.json());
app.use(cors());
app.post('/signin', (req,res)=>{
if(req.body.email===database.users[0].email && req.body.password===database.users[0].password){
res.json('success');
}
else{
res.status(400).json("error");
}
})
PS:Reactapp is running on port 3001 and server on port 3000.
also when i try signing in the request is in form of get method although i am using post method

Network error React(frontend) and Nodejs(backend)

I am unable to link my frontend(React) and backend(Nodejs) together with Axios as it keeps encountering Network Error (I have also included CORS into my backend application but it still does not work). The backend runs on Postman too but not when integrated with the frontend. Frontend is running at localhost:3000 while backend runs at localhost:5000
Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:83)
Here is what my code looks like:
Frontend:
axios.get("http://localhost:5000")
.then((res) => {
console.log(res.data);
alert("Hi succeedd");
})
.catch((err) => {
console.error(err);
alert("Try again");
});
Backend:
const express = require("express");
const connectDB = require("./config/db");
var cors = require("cors");
const app = express();
app.use(cors({ origin: true, credentials: true }));
//Connect to database
connectDB();
//Init middleware to read data sent in req.body
app.use(express.json({ extended: false }));
app.get("/", (req, res) => res.send("API running"));
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on ${PORT}`));
have you set up proxy in your package.json correctly?
you should add this line: "proxy": "http://localhost:5000" so that the it knows to proxy requests between a local frontend and backend
see this for more details: https://www.twilio.com/blog/react-app-with-node-js-server-proxy

Get empty req.body when deployed on Heroku

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)
})

Resources