EDIT: Kevin B answered my question in a comment below. I added some logic to send a 200 request if an OPTIONS http request hit my API to fix the problem. Here is the code:
var allowCrossDomain = function(req, res, next) {
if ('OPTIONS' == req.method) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.send(200);
}
else {
next();
}
};
router.use(allowCrossDomain);
Original Question:
I currently am trying to get an Ionic 2 application running on my localhost to be able to send data to an Express 4 application. It works when I send requests without an authorization header. However, once I added auth headers, my API began to throw errors. I have done my research and have tried to implement what I found here: (https://stackoverflow.com/a/15254158/5379931.
However, I am getting errors still. If I set Access-Control-Allow-Origin like this:
res.header("Access-Control-Allow-Origin", "http://localhost:8100");
I get this error:
XMLHttpRequest cannot load URL. Response to preflight request doesn't pass
access control check: The 'Access-Control-Allow-Origin' header has a value
'http://localhost:8100/' that is not equal to the supplied origin. Origin
'http://localhost:8100' is therefore not allowed access.
If I set my Access-Control-Allow-Origin header like this:
res.header("Access-Control-Allow-Origin", "http://localhost:8100/");
I get this error:
XMLHttpRequest cannot load URL. No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'http://localhost:8100' is
therefore not allowed access. The response had HTTP status code 400.
Here is the rest of my express 4 code that is relevant:
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:8100");
res.header("Access-Control-Allow-Headers", "Origin, Authorization, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
next();
});
It looks like you forgot to respond to the options request. By not responding, it will go to your error handler and be dealt with as if it were an error.
Just send a 200 status within your .use if it is an options request so that it doesn't reach your error handler.
Related
When I perform certain requests, I get this error :
Access to XMLHttpRequest at 'https://myApi/myRoute' from origin 'http://localhost:19006' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
but my app is configured like this :
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:19006");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
If I use this syntax I get the same problem :
app.use(cors({
origin: true, credentials: true
}));
How it is possible that certain requests like login etc .. are ok, but some other are not ?
I work on expo for a react native app in web browser version.
I'm workding on a login demo page. The login server is different with the authserver.
The main page is runing on localhost:3000 and the login server is runing on localhost:4000
The POST request from main page is blocked by CROS policy.
After some googling. I added Access-Control-Origin header to the response. But browser still says
Access to fetch at 'http://localhost:4000/login' from origin 'http://localhost:3000' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The login server code is like this.
app.post('/login',(req,res)=>{
const username = req.body.username;
const password = req.body.password;
let userexist = userinfo.find(user=>user.username===username);
if (userexist&&password===userexist.password) {
const accessToken =JWT.sign(username, process.env.accTokenSecret);
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Credentials',true);
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-PINGOTHER,Content-Type, Accept");
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.status(200).json({'accesstoken':accessToken});
}else{
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Credentials',true)
res.status(404).json({status:'error',error:'user/password is incorrect'})
}
});
after some more googling I find out that I need to handle the preflight request.So here is my code.
app.options('/login',(req,res)=>{
console.log(req);
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Credentials',true);
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-PINGOTHER,Content-Type, Accept");
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.status(200);
});
This time, the browser does not show error. But it seems the actual POST request to send username and password did not send after the preflight request.
What did I do wrong? And what should I do if not using cors middleware. Because I'm trying to understand what's actually happend. If using cors middleware. It hide out the details.
Thanks
I find out how to sort this out. Put the function to sent the header in app.use block will be able to handle the preflight request and the actual response.
app.use(function(req, res, next) {
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",
"GET, POST, PUT, DELETE"
);
next();
});
I get this error when making a GET over 'https://www.google.com/'.
Failed to load https://www.google.com/: 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:4200' is therefore not allowed access. The response had HTTP status code 405.
On server side I use cors:
server.use(cors({
origin: '*',
credentials: true
}));
server.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,
Content-Type, Accept");
next();
});
server.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
next();
});
On client side I have a cookieService:
getCookies(URL) {
const headers = new Headers();
**headers.append('Access-Control-Allow-Origin', '*');**
return this.http.get(URL, { headers: headers }).map(res => res.json());
}
On an angular component I call this function:
searchCookies() {
this.cookieService.getCookies('https://www.google.com').subscribe();
}
Is there a way to add this header to the GET response? Or is there another way to acces to an external URL like https://www.google.com?
Thanks! :)
CORS headers, which you are adding to localhost via your server response, do not work for google - the whole idea of CORS is that the 3rd party server (in this case https://google.com) can defend itself from Cross Origin Resource Sharing.
TL;DR - https://google.com doesn't allow localhost to access the website. If you want to scrape the website - you'd have to access it from node.js itself, rather than client-side JS.
As stated in the title of this question, i'm having CORS issues with a fetch method. Here are the solutions i've tried. Obviously none have worked.
Actual console error:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
I tried to fix the issue via my Express server. I am configuring this before I establish my routes.
import cors from 'cors';
app.use(cors({
origin: '*',
}));
Also tried it this way.
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();
});
Client side service. Set {mode: 'cors'} object.
fetch(requestUrl, {mode: 'cors'}).then((response) => {
return response.json();
}).then((restaurants) => {
resolve(restaurants);
}).catch((err) => {
reject(err);
});
At this point, i'm lost. I'm just trying to get data back from google maps api. Any help would be grateful.
I am tired to resolve my error when I am connected my front end React App with my Heroku server App and when I fire a request from my front-end so that time I am getting this issue:
Failed to load https://hidden-reaches-90171.herokuapp.com/GETDATA: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access.
Can anyone face this issue sol please guide me what I am doing wrong,
Thanks
Try the following code on your main server file in nodejs.
app.all('/*', function(request, response, next) {
response.header("Access-Control-Allow-Origin", "*");
response.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
response.header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept');
if (request.method == 'OPTIONS') {
response.status(200).end();
} else {
next();
}
});