I'm hosting a node.js backend and Postgres database on Heroku. After Heroku started requiring ssl, any requests to the database stopped working. I followed the documented fix here but I'm still getting errors. The request just hangs and eventually errors out as a CORS error.
"Access to XMLHttpRequest at [...] from origin [...] has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."
Database requests work locally both in browser and Insomnia. I also tried making new Heroku projects but still run into the same error when making database requests.
Here is my db.js:
const { Client } = require("pg");
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});
client.connect();
module.exports = client;
app.js:
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.use(express.json());
// add logging system
const morgan = require("morgan");
app.use(morgan("tiny"));
const villagersRoutes = require("./routes/villagers");
const wakeRoutes = require("./routes/wake");
app.use("/villagers", villagersRoutes);
app.use("/", wakeRoutes);
/** 404 Not Found handler. */
app.use(function (req, res, next) {
const err = new Error("Not Found");
err.status = 404;
next(err);
});
/** Generic error handler. */
app.use(function (err, req, res, next) {
if (err.stack) console.error(err.stack);
res.status(err.status || 500).json({
message: err.message,
});
});
module.exports = app;
server.js:
const app = require("./app");
app.listen(process.env.PORT || 5000, function () {
console.log("Server is listening on port 5000");
});
Related
I am deploying the server part of a project, built in node and express and it says that the server is live but it doesn't work. In console I get the errors:
" Failed to load resource: the server responded with a status of 404 ()",
" Refused to load the stylesheet 'https://fonts.googleapis.com/css?family=Lato:300,400,700,900' because it violates the following Content Security Policy directive: "default-src 'none'". Note that "style-src-elem" was not explicitly set, so 'default-src' is used as a fallback.".
I don't understand why it gives me that error, since there is no css or html file...
here is my entry js file:
const express = require('express')
const app = express()
const mongoose = require('mongoose')
const xss = require('xss-clean')
const mongoSanitize = require('express-mongo-sanitize')
const { handleError, convertToApiError } = require('./middleware/apiError')
const routes = require('./routes')
const passport = require('passport')
const { jwtStrategy } = require('./middleware/passport')
require('dotenv').config()
const mongoUri = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}#${process.env.DB_HOST}? retryWrites=true&w=majority`
mongoose
.set("strictQuery", false)
.connect(mongoUri, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then((x) => {
console.log(
`Connected to Mongo! Database name: "${x.connections[0].name}"`
)
})
.catch((err) => {
console.error("Error connecting to Mongo: ", err)
})
//// body parse
app.use(express.json())
//// sanitize
app.use(xss())
app.use(mongoSanitize())
//// passport
app.use(passport.initialize())
passport.use('jwt', jwtStrategy)
//// routes
app.use('/api', routes)
//// handle errors
app.use(convertToApiError)
app.use((err, req, res, next) => {
handleError(err, res)
})
const port = process.env.PORT || 5005
app.listen(port, () => {
console.log(`Server is running on port ${port}`)
})
I don't even know what I could do...
different response result when I use localhost url or the heroku url
As you can see in the picture, in blue we succesfully have the result response. But not when hosted in heroku (green on picture).
Here is the response from api when I try to fetch:
response
But those params are set in .env file (backend).
Can someone help me with this ? The cors is configured on the backend, so I don't know what I can do more...
server.js:
const express = require("express");
const path = require("path");
const bodyParser = require("body-parser");
const cors = require("cors");
const dotenv = require("dotenv");
const colors = require("colors");
const dbConnect = require("./database/dbConnect");
dotenv.config();
// *** ROUTES IMPORT ***
const usersRoutes = require("./routes/users-routes");
const ovhRoutes = require("./routes/ovh-routes");
const renewDomainsRoutes = require("./routes/renew-domain-routes");
const meRoutes = require("./routes/me-routes");
const internetBsRoutes = require("./routes/internetbs-routes");
const domainsRoutes = require("./routes/domains-routes");
const orderRoutes = require("./routes/order-routes");
// execute database connection
dbConnect();
const app = express();
app.use(bodyParser.json());
app.use(cors());
/**
* ROUTES
*/
app.use("/api/users", usersRoutes); // => /api/users/...
app.use("/api/ovh", ovhRoutes); // => /api/ovh/...
app.use("/api/renew", renewDomainsRoutes);
app.use("/api/me", meRoutes);
app.use("/api/internetbs", internetBsRoutes);
app.use("/api/domains", domainsRoutes);
app.use("/api/order", orderRoutes);
app.use((req, res, next) => {
throw new HttpError("Could not find this route.", 404);
});
app.use((error, req, res, next) => {
if (res.headerSent) {
return next(error);
}
res.status(error.code || 500);
res.json({ message: error.message || "An unknown error occurred!" });
});
/**
* DEPLOYMENT
*/
if (process.env.NODE_ENV === "production") {
// Step 1:
app.use(express.static(path.resolve(__dirname, "./client/build")));
// Step 2:
app.get("*", function (request, response) {
response.sendFile(path.resolve(__dirname, "./client/build", "index.html"));
});
}
app.listen(
process.env.PORT || 5000,
console.log(`Server is running on port ${process.env.PORT}`.blue.bold)
);
The data are fetched from internet.bs API.
Thanks all!
I deployed my API to Heroku and when I try to use it (login). I get some errors.
my code -
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const cors = require("cors");
// IMPORT FILES
const user = require("./routes/user");
// MONGOOSE CONNECTION
mongoose.connect(
"CONNECTION URL HERE",
{ useNewUrlParser: true },
() => {
console.log("Connected to DB");
}
);
// MIDDLEWARE CONFIGS
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
mongoose.Promise = global.Promise;
// ROUTES REDIRECTION
app.use("/", user);
// SERVER
const server = app.listen(process.env.PORT || 8080, () => {
const port = server.address().port;
console.log(`Server is running on port ${port}`);
});
JWT FILE
const jwt = require("jsonwebtoken");
module.exports = function (req, res, next) {
const token = req.header("token");
if (!token) return res.status(401).send("please login again");
try {
const verify = jwt.verify(token, "JWT SECRET HERE");
req.user = verify;
next();
} catch (err) {
res.status(400).send("invalid token");
}
};
Some pictures of errors-
Error in Heroku logs --tails
error is browser
PS: i had .env for the variables but took 'em out for delpoyment's sake as I was getting Application error.
thank you! help is appreciated.
Have you added your environment variables to heroku config vars?
If not then follow the heroku documentation to do so.
https://devcenter.heroku.com/articles/config-vars
You can use the heroku cli or use the heroku dashboard to add the variables. Refer the docs for a detailed explanation.
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 have a very simple nodejs server, but using the 'cors' package seems to not recognize the origin of the request for some reason.
Here is my nodejs server config:
const cors = require('cors');
const express = require('express');
const CORS_WHITELIST = [ 'http://localhost:5000' ];
const corsOptions = {
origin: (origin, callback) => {
console.log(origin) // ----> this is always 'undefined'
if (CORS_WHITELIST.indexOf(origin) !== -1){
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
};
const configureServer = app => {
app.use(cors(corsOptions));
};
module.exports = configureServer;
Here is my server starter file:
const express = require('express');
const SERVER_CONFIGS = require('./constants/server');
const configureServer = require('./server');
const configureRoutes = require('./routes');
const app = express();
configureServer(app);
configureRoutes(app);
app.listen(SERVER_CONFIGS.PORT, error => {
if (error) throw error;
console.log('Server running on port: ' + SERVER_CONFIGS.PORT);
});
I am running this server on localhost, but the origin in the cors callback is always 'undefined'. For example when I open http://localhost:5000 on the browser or do a curl call.
How can I use cors so that it doesn't block the request on localhost?
I read this issue and req.headers.origin is undefined question and also CORS and Origin header!
source:
The origin may be hidden if the user comes from an ssl encrypted website.
Also: Some browser extensions remove origin and referer from the http-request headers, and therefore the origin property will be empty.
There is a solution to solve this by adding a middleware:
app.use(function (req, res, next) {
req.headers.origin = req.headers.origin || req.headers.host;
next();
});
I hope these helps. The issue is in awaiting more info state!