I have problem with CORS on Heroku.
This is my code on server
import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
require('dotenv').config()
import filmRoutes from './api/routes/films'
import userRoutes from './api/routes/users'
const app = express()
const DBNAME = process.env.DB_USER
const DBPASSWORD = process.env.DB_PASS
mongoose.connect(`mongodb://${DBNAME}:${DBPASSWORD}@ds157422.mlab.com:57422/filmbase`, {useNewUrlParser: true})
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
next();
});
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use('/films', filmRoutes)
app.use('/users', userRoutes)
export default app;
This is my post request
CheckLogin = () => {
const data = {
name: this.state.formInput.login.value,
password: this.state.formInput.password.value
}
axios.post('https://whispering-shore-72195.herokuapp.com/users/login', data)
.then(response=>{
console.log(response);
const expirationDate = new Date(new Date().getTime() + response.data.expiresIn * 1000)
localStorage.setItem('token', response.data.token)
localStorage.setItem('expirationDate', expirationDate)
this.context.loginHandler()
})
.catch(err=>{
console.log(err)
})
console.log(data);
}
This is ERROR
Access to XMLHttpRequest at 'https://whispering-shore-72195.herokuapp.com/users/login' from origin 'https://mighty-citadel-71298.herokuapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I tried a lot of methods and nothing... any idea?
To quickly fix it, use one of the public CORS proxy servers. I use Heroku CORS proxy server in this example. Append the proxy server to your API URL. You may get the 403 forbidden error even after adding the Heroku CORS proxy URL.
To get rid of a CORS error, you can download a browser extension like CORS Unblock. The extension appends Access-Control-Allow-Origin: * to every HTTP response when it is enabled. It can also add custom Access-Control-Allow-Origin and Access-Control-Allow-Methods headers to the responses.
To resolve a CORS error from an API Gateway REST API or HTTP API, you must reconfigure the API to meet the CORS standard. For more information on configuring CORS for REST APIs, see Configuring CORS for a REST API resource. For HTTP APIs, see Configuring CORS for an HTTP API.
You've cross origin domain on https://whispering-shore-72195.herokuapp.com from origin https://mighty-citadel-71298.herokuapp.com
You can try npm cors package as middleware instead of your custom middleware. CORS
package allows you multiple configure and it's very easy to use.
Simple Usage (Enable All CORS Requests)
import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import cors from 'cors';
require('dotenv').config()
import filmRoutes from './api/routes/films'
import userRoutes from './api/routes/users'
const app = express()
const DBNAME = process.env.DB_USER
const DBPASSWORD = process.env.DB_PASS
mongoose.connect(`mongodb://${DBNAME}:${DBPASSWORD}@ds157422.mlab.com:57422/filmbase`, {useNewUrlParser: true})
/*app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
next();
});*/
app.use(cors()); // <---- use cors middleware
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use('/films', filmRoutes)
app.use('/users', userRoutes)
export default app;
I've test your client call login to your server from https
and it's working without CORS problem. Maybe you had fixed it successfully.
I've tried with simple on StackBlitz and it's working successfully.
You can try login https://js-53876623.stackblitz.io/ and view network tab when inspecting and see OPTIONS (200 status)
and POST (404 not found)
(because I don't know any user in your database)
I've tried your code on my local, maybe you hadn't tested and handled all error, it makes your app crash unfortunately.
I've run your code and noticed the problem maybe jsonwebtoken
error:
Error: secretOrPrivateKey must have a value
Please tried with process.env.JWT_KEY || 'Require key here!!!',
, and set your JWT_KEY
on your environment or use ||
as default key on server.
Maybe it will fix your problem.
I have some recommends for your code:
User.findOne()
instead of User.find()
app.use(cors());
jsonwebtoken
should use Asynchronous instead of Sync when run on server.You need to determine if it is indeed a CORS issue or your API code is breaking.
If it's a CORS issue, handle CORS in your backend code like it's been suggested above or use the cors
package.
However, often times than not, the issue is that your code is breaking and you just didn't know. In my case, for instance, I didn't add nodemon
to the dependencies and my start
script is dependent on nodemon
which Heroku could not find. So it's possible that your code works fine in dev but breaks in prod.
Here's how you can find what part of your code is breaking within Heroku:
503 Service Unavailable
as indicated below, that is an indication again that your code is breaking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With