Reputation: 89
I'm new at ReactJS but I'm trying to learn by myself now. I'm facing a problem when I try to add data do may Database, in my RestAPI with MongoDB, using fetch function on my web Application. When I click my button, it runs the following code:
SubmitClick(){
//console.log('load Get User page'); //debug only
fetch('http://localhost:4000/users/', {
method: 'POST',
headers: {
'Authorization': 'Basic YWRtaW46c3VwZXJzZWNyZXQ=',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: '[email protected]',
first_name: 'Wade',
last_name: 'Wilson',
personal_phone: '(11) 91111-2222',
password: 'wolv3Rine'
})
})
//this.props.history.push('/get'); //change page layout and URL
}
and I get the following message on my browser:
OPTIONS http://localhost:4000/users/ 401 (Unauthorized)
Failed to load http://localhost:4000/users/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Uncaught (in promise) TypeError: Failed to fetch
My RestAPI have Basic Auth, but i don't know what i'm supposed to insert in headers to have access. I got this 'Authorization': 'Basic YWRtaW46c3VwZXJzZWNyZXQ=',
from Postman, when I configured the Authorization tab, and it was automatically added to the headers.
I'm using Google Chrome as my default browser.
My backend code is the following:
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
var basicAuth = require('express-basic-auth')
const app = express();
mongoose.connect('mongodb://localhost/usersregs', { useMongoClient: true });
mongoose.Promise = global.Promise;
app.use(basicAuth({
users: {
'admin': 'supersecret',
'adam': 'password1234',
'eve': 'asdfghjkl'
}
}))
app.use(bodyParser.json());
app.use(function(err, req, res, next){
console.log(err);
//res.status(450).send({err: err.message})
});
app.use(require('./routes/api'));
app.listen(4000, function(){
console.log('Now listening for request at port 4000');
});
Upvotes: 2
Views: 18902
Reputation: 2982
It may not be the same problem as the OP, but I was able to get basic auth protected fetch
es working just by adding a credentials mode...
fetch(
'http://example.com/api/endpoint',
{ credentials: "same-origin" }
)
See here: https://github.github.io/fetch/ under Request > Options
Upvotes: 6
Reputation: 735
You're trying to access port 4000 (your API, or backend) from port 3000 (Your client). This violates the Same-origin policy, even though you're clearly running both the client and the API from the same machine.
To get around this the easiest way is to just fire up your client from the same port as your API (port 4000) this should allow your host to see that you're trying to access resources from the same domain/port which won't force a preflight request.
If that's not possible you'll have to configure CORS for your API, and this question doesn't give any details about the backend so I can't instruct you on how to do that at the moment.
And of course this approach obviously won't work if you're running two separate servers in production, but that's probably outside of the scope of this question.
Upvotes: 2