CORS is blocking response for no reason - javascript

I am making POST request to my server and browser is blocking response with CORS policy (missing Access-Control-Allow-Origin header), but when I request the same url via Postman the header is there. This are my response headers from Postman:
And this is browser (chrome in this case) error when I try to do POST request:
What it's going on?

In case of non-simple request, browser make preflight OPTIONS request to the same url to check if the server allows cross-site requests. So adding new route for OPTIONS requests where I allowed all CORS restrictions solved the problem.
...
if (webServer.method() == HTTP_OPTIONS) {
webServer.sendHeader("Access-Control-Allow-Origin", "*");
webServer.sendHeader("Access-Control-Allow-Methods", "*");
webServer.sendHeader("Access-Control-Allow-Headers", "*");
webServer.sendHeader("Timing-Allow-Origin", "*");
webServer.send(204);
} else {
...

Related

I receive a 404 HTTP error with an API using javascript but not in my terminal

I am using the Pons dictionary API documented here: https://en.pons.com/assets/docs/api_dict.pdf
It works when I use a get request in my mac terminal, but not when using XMLHttpRequest in my javascript file (shown below) when testing it in my browser. It always gives me a 404 error and then states
"Access to XMLHttpRequest at 'https://api.pons.com/v1/dictionary?q=casa&l=dees' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
Any ideas?
I have tried making a request that does not require my X-Secret (credentials) and it works, but as soon as I set the X-Secret header it throws a 404 error. I need to set this heading for most request types.
Here is my code. I have censored my credentials in the X-Secret header.
var request = new XMLHttpRequest()
let url = new URL('https://api.pons.com/v1/dictionary');
url.searchParams.set('q', 'casa');
url.searchParams.set('l', 'dees');
request.open('GET', url);
//request.withCredentials = true;
request.setRequestHeader("X-Secret", "***");
request.setRequestHeader("Access-Control-Allow-Origin", "*");
request.setRequestHeader("Access-Control-Allow-Credentials", "true");
request.setRequestHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
request.setRequestHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization");
request.send()
request.onload = function() {
// Begin accessing JSON data here
var data = JSON.parse(this.response)
if (request.status >= 200 && request.status < 400) {
console.log(data)
} else {
console.log('error')
}
}
CORS is "cross-origin resource sharing"; specifically, it's used to refer to policies that block requests between different domains. In this case, XHR is sending a "preflight request" -- that is, a request with verb OPTIONS (rather than GET, POST, etc.) -- to make sure the server will accept a real request. It will do this whenever you use non-standard (and some standard but optional) headers. The preflight request is coming back as 404; the server doesn't support OPTIONS to that endpoint.
The way to get around CORS is to use a proxy. That is, have a backend script (in Node, PHP, whatever) on your domain that sends the request to the other API server and echoes its response. CORS only applies to AJAX requests, not backend ones, so this will get around the issue, and it is the accepted technique.

No Access-Control-Allow-Origin error in Meteor app

I added CORS extension to chrome. When called ajax from localhost I got response in the form of XML. If I disabled CORS extension I got the following error. I referred so many questions in this community. But I cant't resolve my problem. It may duplicate but I'm asking this question for help with hope.
XMLHttpRequest cannot load https://buzz.machaao.com/feed. 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..
And my code is
HTTP.get('https://buzz.machaao.com/feed',{
headers: {
"Access-Control-Allow-Origin" : "*"
}
}, (err, res) => {
if(err) {
console.log(err);
}
else {
console.log(res);
}
});
The https://buzz.machaao.com/feed site doesn’t send the Access-Control-Allow-Origin response header, so you need to make your request through a proxy instead—like this:
var proxyUrl = 'https://cors-anywhere.herokuapp.com/',
targetUrl = 'http://catfacts-api.appspot.com/api/facts?number=99'
HTTP.get(proxyUrl + targetUrl,
(err, res) => {
if(err) {
console.log(err);
}
else {
console.log(res);
}
});
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS explains why browsers won’t let you access the response cross-origin from frontend JavaScript code running in a web app unless the response includes an Access-Control-Allow-Origin response header.
https://buzz.machaao.com/feed has no Access-Control-Allow-Origin response header, so there’s no way your frontend code can access the response cross-origin.
Your browser can get the response fine and you can even see it in browser devtools—but your browser won’t expose it to your code unless it has a Access-Control-Allow-Origin response header. So you must instead use a proxy to get it.
The proxy makes the request to that site, gets the response, adds the Access-Control-Allow-Origin response header and any other CORS headers needed, then passes that back to your requesting code. And that response with the Access-Control-Allow-Origin header added is what the browser sees, so the browser lets your frontend code actually access the response.

Response to preflight request doesn't pass access control check NodeJS/Heroku/Express

I'm using an Express app on Heroku. I try to make a RESTful request to it from another NodeJS app.
Here's a snippet from the Heroku app, called app.js:
var express= require("express");
app.get("/results",function(req,res){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
});
And here's a snippet from an app I run locally, local-app.js:
var request= require("superagent");
var req= request.get("http://url-to-app-js.com?query=1").set(
"Access-Control-Allow-Origin", "http://url-to-app-js.com",
"Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS",
"Access-Control-Allow-Headers", "Content-Type, Authorization, Content-Length, X-Requested-With"
);
req.end(function(err,res){
// do things
});
When I run local-app.js, I got this error in my browser console: esponse 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.
I know that I could run the browser, Chromium, with certain security settings turned off, but I need to be able to run this without doing so.
What am I doing wrong? How do I fix it?
Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers are response headers. They shouldn't appear in the request at all.
By adding non-standard headers you make the request a preflighted request instead of a simple request. (You might be doing something else that makes it a preflighted request, but the extra headers definitely do not help).
A preflighted request sends a OPTIONS request to find out if it is allowed by CORS before making the request (GET in this case) you actually want to make.
You are only setting the CORS response headers when you receive a GET request. Since you don't respond with them to the OPTIONS request, the browser refuses to make the GET request.

CORS error in JS (XMLRequest)

I’m trying to communicate a web page with a RestAPI server. When I try to do an http request the following message appears:
XMLHttpRequest cannot load https://(MyUrl). Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); //Some line in my web page code
response.setRequestHeader("Access-Control-Allow-Origin", "*"); //Some line in my APIRest code
I have been doing some research about CORS and I don't understand which headers I have to include to the http request and what headers I have to include in the server to enable it. Should I add something in some .config?
For what I have understood, my petition is a “not-simple” request, as it’s a multipart request with an application/json part that also sends a token into the header. It’s a POST request.
Thanks!
It does not help that you set the headers in the client side. The server needs to have that header present in order to allow requests from third parties.
And so this will not work for you as long as the server does not have the Access-Control-Allow-Origin header set to allow your requests.
You can read more about CORS here.

$http Cross domain access issue exists in header

A request is sent through Angularjs $http with JSON data to my REST service. When the response is returned, required headers are set as following,
Response.ok()
.entity(emp)
.headers.add("Access-Control-Allow-Origin", "*")
.headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.allow("OPTIONS").build();
But when I send a post request without data,
$http.post('localhost:8000/employer/register')
it is successful. With data, it fails.
$http({method: 'post', url:serverUrl, data:{name:'abc'}, headers:{'Content-Type':'application/json'} });
This is my Rest service
#Path("/register")
public class EmpService{
#Get
#Path("test")
#Produces
public String test(){
return "works";
}
#Post
#Consumes(MediaType.APPLICATION_JSON)
public Response addEmp(Emp emp){
return Response.ok()
.entity(emp)
.headers.add("Access-Control-Allow-Origin", "*")
.headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.allow("OPTIONS").build();
Browser console is as following.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8081/employer/register (Reason: CORS header 'Access-Control-Allow-Origin' missing).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8081/employer/register (Reason: CORS request failed).
UPDATE: I found that service is not invoked as no Sys.out.println gives any logs.
Anyone know where the problem is?
Don't add the headers inside the resource method. Why? The preflight is an OPTIONS request, which is the "pre"-request to get the access control headers. And you don't have an OPTIONS method. The browser will not call the #POST method to get the access control headers. For this reason, you should be using a filter instead, and set the headers there.
Try this.May be your api route of server not allowed headers data that may be caused problem
$http.post(url:serverUrl, data:{name:'abc'} } );
Maybe you should be sending a header not allowed by the server.
Try this:
headers.add("Access-Control-Allow-Headers",
"Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, otherCustomHeader");

Categories