No 'Access-Control-Allow-Origin' header in some chrome version - node.js

I am trying to upload some images to cloudinary through my client, it works fine on localhost, and in chrome version 87, but in chrome v89 i get No 'Access-Control-Allow-Origin' header error, any ideas on why this is happening?
this is my server route:
const uploader = require('../config/cloudinary.config')
router.post('/upload', uploader.single("imageUrl"), (req, res) => {
res.setHeader('Access-Control-Allow-Origin', 'client domain');
if (!req.file) {
res.status(500).json({ code: 500, message: 'Error loading the file' })
return;
}
res.json({ secure_url: req.file.path })
})
and this is my cors config:
const cors = require('cors')
const whitelist = [process.env.DOMAIN]
const corsOptions = {
origin: (origin, cb) => {
const originIsWhitelisted = whitelist.includes(origin)
cb(null, originIsWhitelisted)
},
credentials: true
}

You probably need to handle CORS preflight requests, which your browser presents as OPTION requests before the POST requests.
Add this line to your code.
router.options('/upload', cors())

Related

Tried everything I find but I can't solve CORS issue with Express server

I'm trying to fetch data from my Express API but I'm keep getting this error.
Firefox Console Error
Chrome Console Error
I have tried everything I find on internet.
I tried using different browser, browser extensions to bypass CORS check.
I thought maybe the issue is related to localhost, so I deployed it, but the same issue persisted.
I tried mockup API with the same frontend, and it fetches data just fine.
I tried manually adding Access-Control-Allow-Origin header on server side but did not work.
I also tried CORS middleware for Express and again did not work.
I'm getting proper responses with Postman just fine, but not within a browser.
This is my code on client side:
async create(visit) {
this.setState({visits: [...this.state.visits, {...visit}]})
fetch('http://localhost:8000/create-visit', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: `{"params": ${JSON.stringify(visit)}}`
})
.then(resolve => resolve.json())
.then(result => {console.log(result)})
}
I also tried GET request with but no difference.
And this is my server side code:
const express = require('express')
const visitRouter = require('./routers/visits')
const cors = require('cors')
const PORT = process.env.PORT;
const app = express();
var corsOptions = {
credentials: true,
origin: "*",
preflightContinue: true,
allowedHeaders: 'GET,PUT,POST,DELETE,OPTIONS'
}
var logger = function(req, res, next) {
console.log(res)
next()
}
app.use(logger)
app.use(express.json())
app.use(visitRouter)
// app.use((req, res, next) => {
// res.append('Access-Control-Allow-Origin', ['*'])
// res.append('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
// res.append('Access-Control-Allow-Headers', 'Content-Type')
// next()
// })
// app.use(cors())
app.use(cors(corsOptions))
app.listen(PORT, () => {
console.log(`Listening from port: ${PORT}`)
})
Router:
const express = require('express')
const router = new express.Router()
const visitModel = require('../models/visits')
router.post('/create-visit', async (req, res) => {
try {
const params = req.body.params
console.log(params)
const newVisit = await visitModel.createVisit(params)
res.status(201).send(newVisit)
} catch (err) {
res.status(500).send(err)
}
})

CORS blocking my node server from react app localhost

Tried everything I could find on here in regards to setting up cors for my node server. Tried aliasing my localhost and that doesn't seem to work either. Also tried using the CORS unblock extension.
error: localhost/:1 Access to fetch at
'http://localhost:8080/api/login' from origin 'http://localhost:3000'
has been blocked by CORS policy: Response to preflight request doesn't
pass access control check: It does not have HTTP ok status.
:8080/api/login:1 Failed to load resource: net::ERR_FAILED
im trying to use magic link authentication in my react app. I got this POST request being made to my node server
const res = await fetch(`http://localhost:8080/api/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + didToken,
},
});
my server code is
const express = require("express");
const cors = require("cors");
const { Magic } = require('#magic-sdk/admin');
require('dotenv').config();
const app = express()
const magic = new Magic(process.env.MAGIC_SECRET_KEY);
app.use("*", (req, res) => res.status(404).json({ error: "not found" }));
// Allow requests from client-side
app.use(cors({origin: process.env.CLIENT_URL}));
app.all('*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.sendStatus(200);
next();
});
app.post('api/login', async (req, res) => {
console.log("login fired")
try {
const didToken = req.headers.authorization.substr(7);
await magic.token.validate(didToken);
res.status(200).json({ authenticated: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = app
app.use(cors({origin: process.env.CLIENT_URL}));
I'd be curious what this URL is. If you want an open CORS policy you don't need to set anything any there.
Put a "/" in front of this route
app.post('/api/login', async (req, res) => {
I was able to reproduce your problem locally and this server setup worked for me to fix it.
const express = require("express");
const cors = require("cors");
const port = 8080;
const app = express();
app.use(cors());
app.post("/api/login", async (req, res) => {
console.log("login fired");
try {
res.status(200).json({ authenticated: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
module.exports = app;

CORS policies issues with Firebase functions

I'm facing a CORS policies issues with Firebase functions even though I think I'm doing the right thing in the backend, I'll show you the code.
const cors = require("cors");
const express = require("express");
const cookieParser = require('cookie-parser');
const app = express();
app.use(
cors({
origin: true,
credentials: true
}),
cookieParser(),
);
This is the function I'm trying to call from the frontend:
app.post("/auth/login", (req, res) => login(req, res));
With this body:
const login = async (req, res) => {
try {
const user = {
id: req.body.id,
password: req.body.password,
};
const auth = getAuth();
const { valid, errors } = validateLoginData(user);
if (!valid)
throw { code: "validation-failed", message: errors, status: 400 };
let data = await signInWithEmailAndPassword(auth, user.id, user.password);
let token = await data.user.getIdToken();
console.log("TOKEN: " + token);
res.cookie("_token", token, { httpOnly: true, maxAge: 3600000 });
return res.status(202).json({ message: "OK" });
} catch (err) {
switch (err.code) {
case "validation-failed":
return res.status(err.status).json({ message: err.message });
case "auth/user-not-found":
case "auth/wrong-password":
return res
.status(401)
.json({ message: "Wrong credentials, please try again" });
default:
return res.status(500).json({ message: err.message });
}
}
};
So here's the problem: when I call this from postman it works, when I call this from my browser (Brave) it doesn't work and it tells me this in the console:
Access to XMLHttpRequest at 'https://europe-west1-stormtestfordota.cloudfunctions.net/api/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
I've tried with many fixes that I found online but none has worked, can you help me please?
CORS is a node.js package for providing Express middleware that can be used to enable CORS with various options.
Enable all CORS requests
Enable CORS for a single route
Configuring CORS
Configuring CORS with dynamic origin
Enable CORS Preflight
Enable CORS asynchronously
If you want to use Express and CORS middleware like that, you should try onRequest functions as shown below:
const express = require('express');
const cors = require('cors');
const app = express(); // Automatically allow cross-origin requests
app.use(cors({ origin: true })); // build multiple CRUD interfaces:
app.get('/test2', (req, res) => { //Handle your test2 methods here
return res.send('your response')
}); // Expose Express API as a single Cloud Function:
exports.api = functions.https.onRequest(app);
Now in this case the CORS middleware you wrote will be running. Your function's URL may look something like - https://us-central1-myapp.cloudfunctions.net/api Then to use the /test2 route it becomes https://us-central1-myapp.cloudfunctions.net/api/test2. CORS shouldn't be an issue anymore here but do note it's an express app now so the parameters in the function are Request, Response instead of data, context.
Also try to follow the steps outlined on https://cloud.google.com/functions/docs/samples/functions-http-cors#functions_http_cors-nodejs and the function will look something like below as in this
exports.hello = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', '*');
response.set('Access-Control-Allow-Credentials', 'true'); // vital
if (request.method === 'OPTIONS') { // Send response to OPTIONS requests
response.set('Access-Control-Allow-Methods', 'GET');
response.set('Access-Control-Allow-Headers', 'Content-Type');
response.set('Access-Control-Max-Age', '3600');
response.status(204).send('');
}
else {
const params = request.body;
const html = 'some html';
response.send(html)
} )};
Also have this essential reading on CORS for better understanding of the issue.

Heroku backend Node.js and Netlify frontend react app has been blocked by CORS policy:

Heroku backend Node.js and Netlify frontend react app has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I've seen a lot of posts on this, but I just can't seem to fix what's creating this error. Of course, I believe it has to do with CORS. But as you can see, I've added multiple versions of CORS middleware to allow this to work. Locally everything is fine. Production/live is where I get the issue:
Access to XMLHttpRequest at 'https://seb-youtube-api.herokuapp.com//videos?page=1&limit=50' from origin 'https://seb-youtube-api.netlify.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Here is my backend server with Node.js and Express.js
They make a simple call to a youtube API.
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser')
const app = express();
const cors = require('cors')
const chalk = require('chalk');
const { google } = require('googleapis');
const youtube = google.youtube('v3'); // initialize the Youtube API library
// Middleware
app.use(cors());
app.use(bodyParser.json());
/******************** GET REQUEST TO VIDEOS *********************/
app.get('/videos', async (req, res) => {
const results = await fetchYoutubePlaylist();
res.json(results)
})
// /******************** POST REQUEST, USER SEARCH *********************/
app.post('/videos', async (req, res) => {
console.log('POST QUERY',req.body)
const query = req.body
res.body = await fetchYoutubeSearch(query)
console.log("RES POST", res.body)
res.json(res.body)
})
app.use('*', cors(), (req, res) => {
return res.status(404).json({ message: 'Not Found' });
});
// CORS
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type,multipart/form-data,Authorization');
res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,DELETE');
if (req.method === 'OPTIONS') {
return res.send(204);
}
next();
});
/******************** FIRST YOUTUBE API CALL *********************/
const fetchYoutubePlaylist = async () => {
try {
const {data} = await youtube.playlistItems.list({
key: process.env.YOUTUBE_API_TOKEN,
part: ['snippet'],
maxResults: 50,
playlistId: "UUBh8XcZST_JTHt-IZDxT_pQ"
})
console.log(data)
return data.items
} catch(err) {
console.log(chalk.red(err))
}
}
/******************** SECOND YOUTUBE API CALL *********************/
const fetchYoutubeSearch = async ({query}) => {
console.log(query)
try {
const {data} = await youtube.search.list({
key: process.env.YOUTUBE_API_TOKEN,
part: ['snippet'],
q: query,
channelId: 'UCBh8XcZST_JTHt-IZDxT_pQ',
order: 'date',
type: 'video',
maxResults: 50
})
console.log('YOUTUBE SEARCH', data)
return data.items
} catch(err) {
console.log(chalk.red(err))
}
}
/******************** LIST TO PORT *********************/
const port = process.env.PORT || 3001;
app.listen(port, () => console.log(`Listing on port ${port}`));
Is the issue that your browser is blocking CORS? That happens to me with Heroku stuff sometimes. There are browser extensions to block/unblock CORS depending on the browser you're using
Stick only with app.use(cors()); that alone should work fine. Instead double check your Config Vars (env vars) on heroku and/or netlify wherever you set such variables. Sometimes that CORS error can be misleading being actually a connection error more about your environment variables.

Lambda (node) Express REST API with AWS API Gateway 502 Bad Gateway error [duplicate]

This question already has answers here:
5xx or 4xx error with “No 'Access-Control-Allow-Origin' header is present”
(2 answers)
aws apigateway lambda always return 502
(4 answers)
AWS API Gateway error response generates 502 "Bad Gateway"
(4 answers)
Closed 2 years ago.
I have a react front app which invokes rest api based on lambda and express. The integration is done via AWS API Gateway. Even the with the cors module I do not achieve what I want.
This is the code:
const express = require('express');
const app = express();
require('dotenv').config();
const youTube = require('./lib/youtube');
const ffmpeg = require('fluent-ffmpeg');
const Logger = require('./lib/logger');
const cors = require('cors');
const serverLogger = new Logger(__filename);
// Init Middleware
app.use(express.json({ extended: true }));
app.use(cors({ origin: true }));
app.get('/', (req, res) => {
res.json({ msg: 'Welcome to the YouTube downloader API...' });
});
app.post('/api/youtube/download', async (req, res) => {
const body = req.body;
const { url } = body;
res.header('Content-disposition', 'attachment; filename=video.mp3');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Methods', 'OPTIONS,POST,GET');
res.header('Access-Control-Allow-Origin', '*');
const youTubeStream = await youTube.getStream(url);
ffmpeg(youTubeStream)
.format('mp3')
.audioBitrate('192k')
.on('end', function () {
console.log('file has been converted succesfully');
res.status(200);
})
.on('error', function (err) {
console.log('an error happened: ' + err.message);
res.status(500).json({ error: err.message });
})
// save to stream
.pipe(res, { end: true });
});
app.post('/api/youtube/info', async (req, res) => {
const body = req.body;
console.log(body);
const { url } = body;
const title = await youTube.getInfo(url);
console.log(title);
res.status(200).json({ title: title });
});
module.exports = app;
I keep on getting this message:
Access to fetch at '...' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Resources