I am calling a fetch request akin to this.
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: new Headers({
'custom-header': 'custom header value'
})
}
)
.then(res=>{
/* code */
})
.catch(err=>{
/* code */
})
But it seems that the header is not being sent to the server. The server runs on Node.js, and I am attempting to reach it with React-Native.
I have allowed "access-control-allow-origin": "*" on the server, but to no avail.
I can also reach other endpoints on the server that don't require any headers.
And lastly, I have set the headers with both new Headers() and as an object.
What exactly am I missing to allow the headers to be sent? Is there a way to see exactly what is going on with my request in react-native?
It works in postman just fine.
EDIT:
I am using the cors middleware in my server.
app.use(cors())
appConfig.init(app);
Can you add these lines before using routes and try?
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, custom-header"
);
res.header("Access-Control-Expose-Headers", "custom-header");
next();
});
And if you are using express cors middleware, you can add allowedHeaders and exposedHeaders options.
https://github.com/expressjs/cors#configuration-options
note if these configuration replaces the default headers, you may need to add the default headers to the options.
app.use(
cors({
exposedHeaders: ["custom-header"],
allowedHeaders: ["custom-header"]
})
);
Lastly you had better to use fetch api like this to send headers:
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: {
"custom-header": "custom header value"
}
}
)
.then(res => {
/* code */
})
.catch(err => {
/* code */
})
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Be sure,you added the header in:
res.header(
"Access-Control-Allow-Headers",
"Your_OWN_header,...."
);
Related
I am trying to send cookies in axios request from request handled in node js, NodeJS Does send cookies in response header but does not set in browser.
ReactJS
axios.post('http://localhost:4000/api/v1/auth/mflogin', {
data: wrapper,
},
)
.then((response) => {
setUser(true);
console.log(response.data);
navigate('/home');
})
.catch((error) => {
console.log('Error adding note.', error);
navigate('/countertwo');
});
This my backend:
One
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('X-Powered-By', '');
next();
});
app.options('*', cors()) // include before other routes
const candidateAuth = require('./routes/Candidate/auth');
app.use('/api/v1/auth/', candidateAuth);
Two
if (validPassword) {
assign(User.dataValues, { Verified: true });
response.cookie('BasicCookie', 'BasicCookie',{httpOnly: true, sameSite: 'strict', secure: 'true',maxAge:1000000000000 }).status(201).json({
User,
});
} else {
response.status(400).json({ error: "Invalid Password" });
}
But it does send cookie to post man request,
But it does come in response header but do not set in cookies?
Any to help me here??
As a starter, I have read a bunch of question concerning the same issue.
When I open the connection with the socket via React client the normal way, just the URL as parameter, I don't get this error, connection established.
But when I do this:
const io = ioClient(webSocketUrl, {
transportOptions: {
polling: {
extraHeaders: getAuthenticationToken()
}
}
});
The request return a CORS error everytime.
I have tried to:
Set the origin like so: io.origins(['*:*']);
app.use(function (req, res, next) {
res.setHeader(
"Access-Control-Allow-Origin",
req.header("origin") ||
req.header("x-forwarded-host") ||
req.header("referer") ||
req.header("host")
);
res.header(
"Access-Control-Allow-Methods",
"GET, POST, OPTIONS, PUT, PATCH, DELETE"
);
res.header("Access-Control-Allow-Headers", "X-Requested-With,content-type");
res.setHeader("Access-Control-Allow-Credentials", false);
next();
});
And also this:
app.use(cors());
app.options("*", cors());
None of the above worked.
I would appreciate any help.
Found the answer!
For anyone with the same problem, this is how I've done it:
const io = require("socket.io")(server, {
handlePreflightRequest: (req, res) => {
const headers = {
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Origin": req.headers.origin, //or the specific origin you want to give access to,
"Access-Control-Allow-Credentials": true
};
res.writeHead(200, headers);
res.end();
}
});
I am getting the cors error. Am I missing anything? Below is the code which I have and the error which I am getting.
App Info:
Back-end is uploaded on lambda using serverless npm === which created api-gateway.
Mongodb is hosted on aws-ec2 instance .
Front-end/React is hosted on s3 bucket.
Thank you so much!
Access to fetch at '[node.js api-url, which is hosted on api-gateway/lambda]' from origin '[front-end react-url, which is hosted on aws-s3 bucket]' 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 'false' which must be 'true' when the request's credentials mode is 'include'.
Node.js code:
db.initialize();
initAxios(defaults);
const app = express();
if (process.env.ENV === 'production') {
app.server = https.createServer(config.sslOptions, app);
} else {
app.server = http.createServer(app);
}
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true,
}));
app.use(expressSession({
secret: process.env.JWT_SECRET_KEY,
resave: true,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());
var corsOptions = {
origin: function (origin, callback) {
callback(null, true)
},
credentials: true
}
app.use(cors(corsOptions));
// I added the below part so maybe it would work but it didn't :)
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();
});
// I added the above part so maybe it would work but it didn't :)
app.use(morgan('combined', {
stream: logger.stream
}));
app.use(`/api/v${process.env.API_VERSION}`, router);
Front-end React Code:
export async function login(data) {
return fetch(`[api-url]auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
// credentials: 'same-origin',
body: JSON.stringify({
username: data.username,
password: data.password,
}),
})
.then((response) => {
return response.json()
})
.then(onSuccess)
.catch(onFail)
}
Before it was like this:
app.use(cors({
credentials: true,
origin: true,
}));
So I converted into:
app.use(cors(corsOptions));
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();
});
Thank you!
Your API endpoint is the API Gateway, not the Lambda, so you need to enable CORS on the actual Gateway.
There are multiple ways of doing this, but if you are using Serverless Framework for your deployment, there is a very good tutorial for enabling CORS here.
The quick and dirty way is just to add 'cors: true' under 'events: -http:' when you're describing your function endpoint in your serverless.yml.
Example:
events:
- http:
path: product
method: post
cors: true
I am trying to prepare a Delete request in AngularJS to a nodeJS local server:
this.deleteMusician = function(id) {
$http({
url: 'http://localhost:3000/musicians/' + id,
method: "DELETE",
data: {}
//processData: false,
//headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
console.log(data);
}).error(function (data, status, headers, config) {
console.log(data);
});
};
And my nodeJS route looks like this:
app.delete('/musicians/:id', musicians.delete);
The same request via PostMan works, but on Google Chrome i get:
OPTIONS http://localhost:3000/musicians/5628eacaa972a6c5154e4162 404 (Not Found)
XMLHttpRequest cannot load http://localhost:3000/musicians/5628eacaa972a6c5154e4162. Response for preflight has invalid HTTP status code 404
CORS is enabled:
var allowCrossDomain = function(req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
};
app.use(allowCrossDomain);
You will need to configure your node server to expect options method too.Check this other answer
so:
app.options('/musicians/:id', optionsCB);
and:
exports.optionsCB = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
next();
}
I have seen many answers in stack overflow which says setting response headers will make you "CORS" request.But no solution worked for me.I have written the following code:
//Server.js Code
var express = require('express'),
app = express();
app.all('*',function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
next();
I am trying to access the content from the URL using $http in client side:
//Controller.js
$http.get('http://domainA.com/a/ipadapi.php?id=135&client=ipad').success(function(response){
alert("I got response");
});
It's showing the following error in console.
XMLHttpRequest cannot load http://domainA.com/a/ipadapi.php?id=135&client=ipad The 'Access-Control-Allow-Origin' header has a value 'http://example.xxxxx.com' that is not equal to the supplied origin. Origin 'http://localhost:3000' is therefore not allowed access.
Note:I am new to nodeJS,Express and AngularJs
When you are passing credentials with CORS, you need to lock down the accepted origins. Try changing your origins from * to "localhost:3000"
See cross origin resource sharing with credentials
Change the header info from
res.setHeader("Access-Control-Allow-Origin", "*");
TO
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
If you're not the owner of domainA then you cannot send CORS headers from that domain. You can use your Node server as middleware, and proxy the request from your server to domainA. Your server can send CORS headers back to your angular app. pseudo code with hapi and needle:
import Hapi from 'hapi'
import needle from 'needle'
const server = new Hapi.Server()
server.connection({
port: 9090
, routes: {
cors: true
}
})
const handler = (req, reply) => {
const url = 'https://domainA.com'
, data = {
body: 'code'
}
needle.post(url, 'body=${data.body}', function(err, res) {
let json = JSON.parse(res.body)
reply(json.data)
})
}
server.route({
method: 'GET',
path: '/route/{id}',
handler: handler
}
)
server.start( err => {
if( err ) {
console.error( 'Error was handled!' )
console.error( err )
}
console.log( 'Server started at ${ server.info.uri }' )
})