OPTIONS request returns "No 'Access-Control-Allow-Origin' header" error during ajax POST to a different domain - ajax

I'm struggling with CORS issue. I make a request from js to a different domain, the method allows cross domain request and all works fine with GET but not with POST request. Looks like OPTIONS method is called before the POST and return standard error
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
return Response.ok().entity(c).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
.header("Access-Control-Allow-Headers", "Content-Type, x-xsrf-token, X-Requested-With, Accept, Expires, Last-Modified, Cache-Control").build();
On the client side I use angularjs
$http.post(url, data).success(...)
But also tried with
$.ajax({type:'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}...})
the same result. what else can I do to fix POST request?

Add the below code to your Angular JS application config file
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

Related

springboot rest api how to answer to a preflight request sent by the CORS

I'm developing a webapp angular-springboot with some other people, and to a few of those certain requests of the app are blocked by the cors with this error:
Access to XMLHttpRequest at 'https://localhost:8443/api/contratto/update' from origin 'http://localhost:4200' 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
so I have researched what a preflight request is and I've added this method to the controller:
#RequestMapping(value = "/update",method = RequestMethod.OPTIONS)
public ResponseEntity<String> preFlightHandler(){
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Access-Control-Allow-Origin",
"https://localhost:8443");
return ResponseEntity.ok()
.headers(responseHeaders)
.body("gggg");
}
but it never even gets executed, how do I create a method mapped specifically for preflights?
didn't make a method mapped for that but I solved the error, Im' using the WebSecurityConfigurerAdapter and in the method configure(HttpSecurity http) I added the line
http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
I have backend API which was accessible with GET, but couldn't be successful with POST, due to PREFLIGHT issue, which incurred CORS blockage.
Thus, in this site,
https://newbedev.com/http-request-from-angular-sent-as-options-instead-of-post#:~:text=HTTP%20request%20from%20Angular%20sent%20as%20OPTIONS%20instead,is%20allowed%20from%20a%20particular%20domain%20as%20follows%3A
I have found that, you just simply play with OPTIONS method, which your browser calls to backend for before "ACTUAL" call. this is called Preflight request.
It uses OPTIONS method instead of get/post/put. Thus, this might be of help.
If you use Node Js Server:
if (req.method == "OPTIONS")
{
res.writeHead(200, {"Content-Type": "application/json"});
res.end();
}
With PHP, I use this code:
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("HTTP/1.1 200 ");
exit;
}
These are my headers in PHP:
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Max-Age: 3600");
header("HTTP/1.1 200");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Authorization, X-Requested-With, Origin");
Note the OPTIONS method in the headers.
If you use other language, that might be easy for you using this concept.
That's it.

Angular2 : X-XSRF-TOKEN is not allowed by Access-Control-Allow-Headers

I am struggling with this issue today as I am implementing a cross-site API call. The worst thing is it works well from my local environment but once on heroku, it fails with the following error:
XMLHttpRequest cannot load https://restcountries.eu/rest/v1/all. Request header field X-XSRF-TOKEN is not allowed by Access-Control-Allow-Headers in preflight response.
Here is the function triggering the call:
let observable = this._http
.get(GEO_API_URL + query)
.map(response => response.json())
.do(val => {
this.cache = val;
observable = null;
})
.share();
return observable;
Any idea ?
Thanks.
Had the same issue.
In my case the reason was that in my Chrome cookies was saved X-XSRF-TOKEN field. And somehow Chrome added header 'Access-Control-Request-Headers: x-xsrf-token' to OPTION request. In Firefox the same page works fine, in incognito mode Chrome - too.
So I've just delete this cookies field (X-XSRF-TOKEN) and that's all.
In my case I had to add the 'x-xsrf-token' value to 'Access-Control-Allow-Headers' header:
header('Access-Control-Allow-Headers: Content-Type, x-xsrf-token')
see AngularJS: POST Data to External REST API
I cleared cookies, this solved problem.
this helped me in java (expose the headers and then include in the allow headers). This will then show in your HttpResponse object:
response.addHeader("Access-Control-Expose-Headers", "header1");
response.addHeader("Access-Control-Expose-Headers", "header2");
response.addHeader("Access-Control-Expose-Headers", "header3");
response.addHeader("Access-Control-Allow-Headers", "Origin, header1, header2, header3, X-Requested-With, Content-Type, Accept");
The reason is that x-xsrf-token keyword is not in response header Access-Control-Allow-Headers.
I solved this problem in java using following solution:
rsp.setHeader("Access-Control-Allow-Methods", "GET,HEAD,POST,OPTIONS,PUT,DELETE,TRACE,CONNECT");
rsp.setHeader("Access-Control-Allow-Headers", "cache-control,content-type,hash-referer,x-requested-with, x-xsrf-token");
if ("OPTIONS".equals(req.getMethod())) {
rsp.setStatus(HttpServletResponse.SC_OK);
return;
}

Access-Control-Allow-Origin in preflight response doesn't enable cross-domain access

I am trying to send a CORS request using AJAX to a nodeJS server. I want to return some JSON data. I've found numerous tutorials online that all say the same thing, which I've tried, but I can't get this to work. Here's the AJAX request:
$.ajax({
url: "http://some.other.url.com:8880",
type: "GET",
crossDomain: true,
contentType: 'application/json'
}).then(function(response) {
$scope.allData = jQuery.parseJSON( response );
console.log($scope.allData);
}).fail(function(response) {
});
And here is the code on the server:
var path = url.parse(req.url).pathname,
match = router.match(path),
rescode;
console.log("---: " + req.method);
if (req.method === 'OPTIONS') {
var headers = {};
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = false;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
res.writeHead(200, headers);
return res.end();
}
I'v also tried it without the return on res.end() i.e. not returning the OPTIONS preflight request, and that doesn't work either.
--Edit--
Here is the actual error message in the console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://other.domain.com:8880/. This can be fixed by moving the resource to the same domain or enabling CORS.
The server is getting the requests. Both the OPTIONS and then GET requests are hitting the server and being responded to. In fact, in the console log for the page making the AJAX request, I can click on the CORS error and see the response, and it is the correct data. But I can't seem to get the javascript to continue.
In regards to .done vs .then, they seem to work interchangeable. Or at least, in this example, the .then and .fail are working just fine.
You're correctly setting CORS headers in your OPTIONS preflight response, but you also need to set Access-Control-Allow-Origin (either to your origin or *) on your actual GET response. The GET response should respond with the same CORS headers, regardless of whether there was a preflight response or not. This means that it must send the appropriate CORS headers, but it does not need to send anything except for Access-Control-Allow-Origin. (If other non-simple components like non-simple verbs or headers are involved, they will be allowed or denied in the preflight; the actual GET response does not need to worry about them.)
The Enable CORS site has a CORS testing tool to help you see the headers involved in a request that you specify. I've used that tool to set up a test similar to your case (GET with non-simple Content-Type header). If we examine the results of that test (careful -- the steps are presented little bit out of order, but they're all there), we see a preflight response:
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
...
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Access-Control-Allow-Headers: X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept
And the final CORS response:
Content-Length: 0
Content-Type: application/json
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Cache-Control: no-cache
As you can see, the GET response also has a Access-Control-Allow-Origin header and no other CORS headers. If you have any further uncertainties, feel free to tweak the settings on that tool to run a wide range of other test cases.

HTTP OPTIONS error in Phil Sturgeon's Codeigniter Restserver and Backbone.js

My backbone.js application throwing an HTTP OPTIONS not found error when I try to save a model to my restful web service that's located on another host/URL.
Based on my research, I gathered from this post that :
a request would constantly send an OPTIONS http request header, and not trigger the POST request at all.
Apparently CORS with requests that will "cause side-effects on user data" will make your browser "preflight" the request with the OPTIONS request header to check for approval, before actually sending your intended HTTP request method.
I tried to get around this by:
Settting emulateHTTP in Backbone to true.
Backbone.emulateHTTP = true;
I also allowed allowed all CORS and CSRF options in the header.
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
The application crashed when the Backbone.emulateHTTP line of code was introduced.
Is there a way to respond to OPTIONS request in CodeIgniter RESTServer and are there any other alternatives to allow either disable this request from talking place?
I found this on Github as one solution. I am not sure if I should use it as it seems a bit outdated.
I encountered exactly the same problem. To solve it I have a MY_REST_Controller.php in core and all my REST API controllers use it as a base class. I simply added a constructor like this to handle OPTIONS requests.
function __construct() {
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
$method = $_SERVER['REQUEST_METHOD'];
if($method == "OPTIONS") {
die();
}
parent::__construct();
}
This just checks if the request type is OPTIONS and if so just dies out which return a code 200 for the request.
You can also modify the $allowed_http_methods property in your subclass to exclude the options method. Previous versions of REST_controller did nothing with OPTIONS and adding this line seems to mimic that behavior:
protected $allowed_http_methods = array('get', 'delete', 'post', 'put');
I solved in this way:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, x_requested_with");
if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
die();
}
Pay attention to add x_requested_with in Access-Control-Allow-Headers.

JQuery ajax OPTIONS authorisation request not working

I'd like to POST data to another domain and receive the confirmation message returned by the action. So to get CORS to work I've got an options action to handle the OPTION HTTP method (on the same path as the POST) in my rails controller, which currently looks like this:
def options
headers['Access-Control-Allow-Origin'] = "*"
headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
headers['Access-Control-Max-Age'] = '100'
headers['Access-Control-Allow-Headers'] = '*, x-requested-with, content-type, accept, origin, referer, user-agent'
render :text => '', :content_type => 'text/plain'
end
My jquery ajax request looks like this: (coffeescript)
$.ajax
type: 'POST'
url: 'http://my-other-domain.com/'
data: data
contentType: "application/json; charset=UTF-8"
crossDomain: true
success: (response) =>
if response.data_saved
...
error: () => ...
but... it don't work.
The OPTIONS request seems to be working, returning Access-Control-Allow-Origin:* and all, the server receives and processes the POSTed data, but Chrome still throws
XMLHttpRequest cannot load http://my-other-domain.com/. Origin http://my-main-domain.com is not allowed by Access-Control-Allow-Origin.
in the console and fires the error callback.
What am I missing?
The Access-Control-Allow-Origin: * header must be included on all responses, not just on the preflight OPTIONS response. Adding that header on the POST response should fix things.
(Also note that '*' is not a valid value in Access-Control-Allow-Headers, but it shouldn't break anything)
I remember that I had a problem like that , the cross ajax problem , in php I resolved that with header("..."); Then I started to use
.getJSON
method in Jquery

Resources