Call NodeJS API With REACT - node.js

Hy, I try to get some data from a nodeJs API. I use react for frontend. I make my node API, I test with Postman and it work fine. When I use axios for get my data from the server I get a cors Error.
This is my axios call from react:
async function getMagazin(){
return (await axios.get(URL)).data;
}
And this is my node Js API:
import express from 'express';
import bodyParser from 'body-parser';
import db from './dbConfig.js';
import Magazin from './entities/Magazin.js';
import cors from 'cors';
let app = express();
let router = express.Router();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use('/api', router);
app.use(cors());
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
if ('OPTIONS' == req.method) {
res.sendStatus(200);
}
else {
next();
}});
async function getMagazin(){
return await Magazin.findAll();
}
router.route('/magazin').get(async (req, res) => {
res.json(await getMagazin());
})
let port = process.env.PORT || 8000;
app.listen(port);
console.log("API is running at " + port);
I try to add cors in my node API and hope the error is gone but not.
This is the error:
I try to make I debug, the api call go on the server and execute sql query, but when he return he give me that error. What I must add in my server side code for the API to work?

Switch the order so that cors is before api
app.use(cors());
app.use('/api', router);

When you use cors you have to indicate what domain or address can contact your api by adding it in the cors middleware like this:
app.use(cors({
origin: "http://localhost:3000"
}));

Related

How to solve cors error in socket.io laravel and nodejs signalling app

i have a chat app built with laravel and socket.io. My laravel app is located on one domain while my nodejs app is on another domain. Connecting to my nodejs signalling app gives a cors error while the nodejs app also returns cors error. Here is my nodejs app
"use strict";
require('dotenv').config();
const express = require('express');
const app = express();
const fs = require('fs');
const options = {
key: fs.readFileSync(process.env.KEY_PATH),
cert: fs.readFileSync(process.env.CERT_PATH)
};
const https = require('https').Server(options, app);
const io = require('socket.io')(https);
io.origins('*:*');
const listner = https.listen(process.env.PORT, function() {
console.log('Listening on ', listner.address().port);
});
//allow only the specified domain to connect
io.set('origins', process.env.DOMAIN + ':*');
require('./socket')(io);
app.get('/', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// Add this
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, OPTIONS');
res.header('Access-Control-Max-Age', 120);
return res.status(200).json({});
}
res.send('Ok');
next();
I have installed a cors middleware on my laravel backend but no difference whatsover. Any help will be appreciated
You need to remove these two line. cos, you have first set for any origin and the you have specified domain with env.
io.origins('*:*');
io.set('origins', process.env.DOMAIN + ':*');
Exact way to allow user is
// process.env.DOMAIN == "https://anydomain.com:port"
// process.env.DOMAIN != "anydomain.com:port"
const options={
cors:true,
origins:[process.env.DOMAIN],
}
const io = require('socket.io')(https, options);

CORS header not applied for a particular route in Express cloud functions

I implemented a basic express app for cloud functions. I have used the cors library to enable cors. There are 4 api endpoints and all 4 need to be preflighted. For some reason, access-control-allow-origin:* header is placed on the 3 routes and not the 4th one.
Precisely, i'm using Content-Type: application/json for POST requests, which need to be preflighted. All the endpoints need the same headers, but it isn't applied for the last one.
Code snippets:
const express = require("express");
const cors = require("cors");
const bodyParser = require('body-parser');
const admin = require("firebase-admin");
admin.initializeApp();
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.use(express.json());
app.use('/', require('./controllers'));
exports.apiv2 = functions.https.onRequest(app);
Routes:
const express = require('express');
const router = express.Router();
router.use('/create-player', require('./createPlayer'));
router.use('/create-game', require('./createGame'));
router.use('/join-game', require('./joinGame'));
router.use('/move', require('./makeMove'));
// 404 error handler for invalid player and game IDs
router.use((err, req, res, next) => {
res.json({ error: err.msg });
});
module.exports = router;
For the /move route alone, the cors request fails, even after preflight request passes. Preflight passes with 204. The actual request fails for some reason. The POST request fails
Is there any particular access control header is not placed by express for one endpoint alone ?
You can set this middleware before your routes middleware in app.js to solve thi problem:
// app.js
...
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
if ('OPTIONS' === req.method)
res.sendStatus(200);
else
next();
});
...
app.use(routes);
Then, this will be applied for all of your routes.

express cors blocked only on root route of some api

i have custom cors settings, due to provide custom OPTIONS method. below code
// region cors
// app.use(cors()); // - fixme > using cors lib will disable http options for all routes. avoid using it.
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Headers", "Authorization");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS")
next();
});
// endregion cors
and here is some route. that behaves weirdly.
const router = express.Router();
router.options(`/`, authMiddleware, options);
router.get(`/term`, authMiddleware, search);
router.get(`/`, authMiddleware, search);
router.get(`/recent`, authMiddleware, getRecentSearchHistory);
export {router}
you can see
~/term and / is identical. which i made ~/term additionally to check if it's working.
the problem is, api request to / will be blocked !!?
for some reason, /term works just fine, but express will block only the / root route.
(which actual abs route is http://localhost:3000/api/search)
does express has route name reservation specifically to "search" or something?
i don't understand this behavior.
I'm not quite sure I understand the question but I'll take a chance at answering anyway..
The router is a new instance of express, it doesn't inherit app's cors setttings, I haven't used express router in a while but I think if you make the router use cors as well it might work, if you want the / route to not get caught by the /* route I suggest maybe defining it above the app route.
Here is an example of what I mean
import express from 'express'
import cors from 'cors';
const router = express.Router();
router.use(cors());
router.options(`/`, authMiddleware, options);
router.get(`/term`, authMiddleware, search);
router.get(`/`, authMiddleware, search);
router.get(`/recent`, authMiddleware, getRecentSearchHistory);
const app = express();
app.use(cors());
app.use(router);
// app.use('/index/', index);
app.listen(3000, () => console.log('app listening'));

How to solve No 'Access-Control-Allow-Origin' in express js?

I know that this question has been answered and some of them worked but for me it is not. I'm struggling to find a solution for this problem:
Access to XMLHttpRequest at 'http://lolcahost:9000/api/users' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I already tried downloading a chrome extension but didn't help me and using app.use(cors()) also didn't help me.
This is my code in expressjs
/* Importing all necessary packages. */
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
/* Default port */
const port = process.env.PORT || 9000;
/* Creating express object */
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/api', require('./routes/route'));
app.use(cors());
app.get('/', (request, response) => {
response.json({
HOME: "HELLO JSON"
})
});
app.listen(port, () => {
console.log(`Listening at port ${port}`)
});
and this is my code in vuejs where I'm trying to render the data.
getUsers() {
axios
.get("http://localhost:9000/api/users/")
.then(response => (this.results = response.data))
.catch(error => console.log(error));
}
You are using the cors middlware AFTER the /api routes. So, actually the cors middlware is not even being called. Put the cors above other middlwares.
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/api', require('./routes/route'));
Middlwares are called by the order they are initialised. Now, the /api is initialised first and is not a middleware(doesn't call the next() function) so after the routes any middleware is basically unreachable code.
Try this.
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:8080"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
or
app.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();
});

connecting to expressjs app from angularjs

I am trying to build an application with angularjs as front end and rest api using express js. I built both the projects using yeoman and my angular app is running on localhost:9000 and my express app is running on localhost:3000. When i try to talk to express js app from angular, I am getting a cross domain request, is there any way to fix this.
app.js in Express App
var routes = require('./routes/signup')(app); //This is the extra line
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "{GRUNT_SERVER}");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
app.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.js in angularjs app
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.withCredentials = true;
Error
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:9000' is therefore not allowed access.
The response had HTTP status code 409.
EDIT
Here's the code that I added to my app.js file:
// allow CORS:
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8000');
next();
});
This also throws the same error ("No 'Access-Control-Allow-Origin' header is present on the requested resource.") as before.
EDIT
After using
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
This is throwing POST localhost:3000/signup 409 (Conflict)
Use npm cors - https://github.com/expressjs/cors to allow cors request.
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
app.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.listen(3000);

Resources