I am trying to connect my front end to my back end, and I am using express server with node and react.
this is my fetch request fom front end: server runs on port 5000
const response = await axios.post("http://localhost:5000/send-email", {
to_email: data.data.email,
url: data.data.url,
});
console.log(response);
this resutls in:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/send-email. (Reason: CORS request did not succeed). Status code: (null).
I have in my back end:
app.post("/send-email", async (req, res) => {
try {
const { to_email, url } = req.body;
console.log(to_email, url);
await sendMail()
.then((result) => console.log("Email sent...", result))
.catch((error) => console.log(error.message));
res.send({ express: "YOUR EXPRESS BACKEND IS CONNECTED TO REACT" });
} catch (error) {
console.log(error);
res.status(500).json({ message: error });
}
});
I am also using core and also something like this:
// app.use(function (req, res, next) {
// // res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Origin", "http://localhost:3000");
// res.header(
// "Access-Control-Allow-Headers",
// "Origin, X-Requested-With, Content-Type, Accept"
// );
// res.header("Access-Control-Allow-Methods", "POST, OPTIONS");
// res.header("Access-Control-Allow-Credentials", true);
// next();
// });
but regards less I keep getting this error and I am not sure how to get rid of it. I have seen several solutions they are either old, and I have tried some of them, they dont work at all.
Install cors using (npm install cors).
In your backend code file, add
var cors = require('cors') <br />
app.use(cors())
Alternatively, follow instructions given at https://www.npmjs.com/package/cors.
I fixed it like the following:
in my front end, I have
const response = await axios.post("http://localhost:8000/signup", {
newUserNameEmail,
url,
});
console.log("response--> ", response.data);
and in my backend server:
const PORT = 8000;
const express = require("express");
const cors = require("cors");
const nodemailer = require("nodemailer");
const { google } = require("googleapis");
const app = express();
app.use(cors());
app.use(express.json());
//sign up
app.post("/signup", async (req, res) => {
try {
const { newUserNameEmail, url } = req.body;
console.log(newUserNameEmail, url);
await sendMail(newUserNameEmail, url)
.then((result) => console.log("Email sent...", result))
.catch((error) => console.log(error.message));
res.status(200).json({ newUserNameEmail, url });
} catch (error) {
console.log(error);
res.status(500).json({ message: error });
}
});
So for some reason, this works and doesn't generate the error I was getting before. I can now communicate with front end and backend and send data, and email.
But I have no idea why this worked and the other one didnt. I also didnt change my package.json
Add proxy in your package.json file to the port of your backend api
"proxy": "http://localhost:8000"
then change your url in the request to port 3000 or wherever your frontend is
const response = await axios.post("http://localhost:3000/send-email", {
to_email: data.data.email,
url: data.data.url,
});
console.log(response);
proxy only works in local, however your app and api usually share the same main domain so this cors error will not appear in production..
Related
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;
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.
I've deploy my node.js server into Azure by new AppService linux.
It correctly start, because if I call one http get it return the correct data.
But when I try to call the post url that make a:
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
// Process bot activity
await botActivityHandler.run(context).catch((e) => { console.dir(e) });
});)}
it return
UnhandledPromiseRejectionWarning: Error: BotFrameworkAdapter.processActivity(): 400 ERROR Error: BotFrameworkAdapter.parseRequest(): missing activity type.
I've already check if the bot have the correct appId and pwd, and it's are ok.
This is my index.js file:
// index.js is used to setup and configure your bot
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
// Import required bot services.
// See https://aka.ms/bot-services to learn more about the different parts of a bot.
const { BotFrameworkAdapter } = require('botbuilder');
// Import bot definitions
const { BotActivityHandler } = require('./botActivityHandler');
// Read botFilePath and botFileSecret from .env file.
const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });
// Create adapter.
const adapter = new BotFrameworkAdapter({
appId: "XXXXXXXXXXXXXXXXXXXXXX",
appPassword: "XXXXXXXXXXXXXXXXXXXXXXX"
});
adapter.onTurnError = async (context, error) => {
console.error(`unhandled error: ${error}`);
console.dir(`unhandled error: ${error}`);
await context.sendTraceActivity(
'OnTurnError Trace',
`${error}`,
'https://www.botframework.com/schemas/error',
'TurnError'
);
await context.sendActivity('The bot encountered an error or bug.');
await context.sendActivity('To continue to run this bot, please fix the bot source code.');
};
// Create bot handlers
const botActivityHandler = new BotActivityHandler();
// Create HTTP server.
const server = express();
server.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
next();
});
server.use(bodyParser.json()); // to support JSON-encoded bodies
server.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
const port = process.env.port || process.env.PORT || 3978;
server.listen(port, () =>
console.log(`service listening at https://localhost:${port}`)
);
// Listen for incoming requests.
server.post('/api/messages', (req, res) => {
console.dir(adapter);
adapter.processActivity(req, res, async (context) => {
// Process bot activity
console.dir(context);
await botActivityHandler.run(context).catch((e) => { console.dir(e) });
});
});
server.post('/api/create/uat', (req, res) => {
console.dir(req.params);
});
server.get('/api/read/uat', (req, res) => {
console.dir(req.params);
});
server.post('/api/prova/post', (req, res) => {
console.dir(req.params);
});
Locally with ngrok it run ok, Can anyone help me?
Thanks.
As suggested by #Leonardo, Local and distributed app can be deleted and setup a new app by changing the URL.
I have been frantically trying for hours to get my email working.
This is the website:https://www.shafirpl.com/contact
I have a react app hosted on the same server ( a digital ocean droplet) as node.js app. The domain name(shafirpl.com) has SSL certificate from cloudflare. The node.js app is running on port 4000 while the react app on port 80. So what is happening now is that the react production build is running on port 80 of that IP address/server, and I have an axios post request when the user clicks the send button. When it was on my local machine it worked as the axios request was using "http://localhost:4000/email". But when I deployed on the server and changed the URL to "http://myServerIpAddress:4000/email" I get the error that says I have to send the request via https. I am not sure how to generate an SSL certificate so that my front end react app can commit the axios request and don't have the issue. I have tried to follow certbot tutorial but it seems like certbot requires a specific domain name. SO what I did is that I created key-cert pairs for my domain name (shafirpl.com) using this tutorial (https://dev.to/omergulen/step-by-step-node-express-ssl-certificate-run-https-server-from-scratch-in-5-steps-5b87) and am using in my server.js file (the node.js app brain) like this:
const express = require("express");
// const connectDB = require("./config/db");
const path = require("path");
const https = require("https");
const fs = require("fs");
// routes variables
const emailRoute = require("./routes/email");
const resumeRoute = require("./routes/resume");
// const authRoute = require("./routes/api/auth");
const app = express();
var cors = require("cors");
// var corsOptions = {
// origin: "*",
// optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
// };
app.use(cors());
app.options("*", cors());
// Connect Database
// connectDB();
// Middleware initialization
/*
* Usually we used to install body parser and do
* app.use(bodyparser.json()). But now bodyparser comes
* packaged with express. So we just have to do express.json()
* to use bodyparser
*/
app.use(express.json({ extended: false }));
// use this when on my pc
// app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "http://localhost:3000"); // 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();
// });
// use this on produnction
// app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "*"); // 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();
// });
// app.get("/", (req,res) => {res.send('API Running')});
// Define Routes
app.get("/", (req, res) => {
res.send("Server Running");
});
app.use("/email", emailRoute);
app.use("/resume", resumeRoute);
// app.use("/api/auth", authRoute);
// app.use("/api/profile", profileRoute);
// app.use("/api/posts", postsRoute);
// // serve static assets in production
// if (process.env.NODE_ENV === "production") {
// // set static folder
// app.use(express.static("client/build"));
// app.get("*", (req, res) => {
// res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
// });
// }
/*
* This means when the app will be deployed to heroku, it will
* look for a port specified by heroku. But since right now
* locally we don't have that, we will be running the app on
* port 5000
*/
// const PORT = process.env.PORT || 4000;
// app.listen(PORT, () => {
// console.log(`Server started on port ${PORT}`);
// });
app.listen(4000);
// comment out this line when testing on localhost
const httpsServer = https.createServer(
{
key: fs.readFileSync("/etc/letsencrypt/live/shafirpl.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/shafirpl.com/fullchain.pem"),
},
app
);
httpsServer.listen(443, () => {
console.log("HTTPS Server running on port 443");
});
And in my axios.post I am using like this
const url = "https://shafirpl.com:443/email";
const sendMessage = async () => {
const config = {
headers: {
'Content-Type': 'application/json',
}
}
const body = JSON.stringify({ name, email, company, message });
try {
const res = await axios.post(url, body, config);
console.log(res);
clearForm();
showSuccessMessage();
} catch (error) {
console.log(error);
showFailureMessage();
}
}
const showFailureMessage = () => {
setFailureAlert(true);
setTimeout(() => {
setFailureAlert(false)
}, 3000);
}
But right now I am again getting this error:
Access to XMLHttpRequest at 'https://shafirpl.com/email' from origin 'https://www.shafirpl.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.
I actually don't know how to solve this as I am pretty new to the total MERN stack build. Can anyone help me with this? I just wanna send email using the axios
I had the same issue - what I did, I removed explicit ports from both server and client. Then I noticed that I was hitting http://mydomain.... please try accessing it from https://mydomain... that did the trick for me :) Hope it helps!
I think i fixed the issue. Instead of running 2 different application, I decided to serve my react build via my node.js app. The way I did was this:
const express = require("express");
// const connectDB = require("./config/db");
const path = require("path");
// routes variables
const emailRoute = require("./routes/email");
const resumeRoute = require("./routes/resume");
const app = express();
app.use(express.json({ extended: false }));
app.use("/api/email", emailRoute);
app.use("/api/resume", resumeRoute);
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
app.listen(80);
Then on my axios request I just did that:
const url = "/api/email"; const sendMessage = async () => {
const config = {
headers: {
'Content-Type': 'application/json',
}
}
const body = JSON.stringify({ name, email, company, message });
try {
const res = await axios.post(url, body, config);
console.log(res);
clearForm();
showSuccessMessage();
} catch (error) {
console.log(error);
showFailureMessage();
}
}
Right now everything is working fine.
For the resume thing which sends a file download, instead of using /api/resume I had to do
something like this
<Nav.Link eventKey="6" activeClassName="active-nav" href="https://shafirpl.com/api/resume" target="_blank" rel="noopener noreferrer">Resume</Nav.Link>
And right now the resume download is also working fine
Thanks for all the help
I'm using googleapis package from node to get refresh token and access token from auth code passed from front-end but every time I get the following error.
{
error: 'redirect_uri_mismatch',
error_description: 'Bad Request'
}
I know this error comes up when we mismatch URL passed as a callback URL in the console.
https://console.cloud.google.com/apis/credentials
but I've already set up the correct URL in the console. still not sure what's the problem with the code.
Using /auth to pass the token from front-end to node-server.
const {
google
} = require("googleapis");
const OAuth2 = google.auth.OAuth2;
var bodyParser = require('body-parser')
const express = require('express');
const app = express();
app.use(bodyParser.json());
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();
});
app.use('/tokenCallback', (req, res) => {
console.log(req);
res.send('An alligator approaches!');
});
app.post('/auth', (req, res) => {
runProcess(req.body.auth);
res.send('An alligator approaches!');
});
app.listen(4300);
function runProcess(code) {
const oauth2client = new OAuth2(
"210347756664-xxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
"57ZU6JuQ7oQ7SvSFtki5atxx", // Client Secret
"http://localhost:4300/tokenCallback",
);
oauth2client.getToken(code, (e) => {
console.log(e);
});
oauth2client.on('tokens', (tokens) => {
if (tokens.refresh_token) {
console.log("refresh token", tokens);
}
});
}
Any help from anyone will be greatly appreciated.
The redirect_uri_mismatch means that your application isn't sending a valid redirect URI, or it is not registered on Google Cloud Console.
Make sure that in Console -> APIs & Services -> Credentials -> OAuth client IDs -> (your key) you have added the http://localhost:4300/tokenCallback URI.