This is pretty much a known standard error but unable to fix the same using existing Stackoverflow posts.
XMLHttpRequest cannot load https://myserver.com/context/
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
Origin 'https://www.otherwebsite.com' is therefore not allowed access.
The response had HTTP status code 405.
Following is the code I have -
function setHeader(xhr) {
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
}
var url = "https://myserver.com/context/";
$.ajax({
url: url,
type: 'GET', dataType:'json',
success: function(data) {
_this.question(data.question);
_this.questionId(data.questionId);
_this.choices(data.choices);
}, error: function() {
console.log("ERROR in getting microquestion");
},
beforeSend: setHeader
});
The “Response to preflight request… had HTTP status code 405.” message indicates, to start, the https://myserver.com/context/ endpoint needs to be configured to handle OPTIONS requests correctly—even if it may already be set to send the right CORS headers back for “normal” requests.
For more details about what’s happening, you can read the How to avoid the CORS preflight section of the answer at No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API — but the gist of it is, minimally, the server must respond to OPTIONS requests with a 2xx success status code.
Related
So I've been experiencing this CORS error and a 401 and have tried chrome plugins to allow for cors with no luck. Here are the errors I'm getting after disabling cors via the plugin:
Access to fetch at 'https://api.playground.klarna.com/payments/v1/sessions' from origin 'https://localhost' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Failed to load resource: net::ERR_FAILED
Error: TypeError: Failed to fetch
Before enabling the CORS Chrome Extension I was receiving a Allow-Access-Control-Origin is not set on the first error message. Along with this in the network tab I'm getting a 401 Preflight which indicates unauthorized but I'm setting the Authorization header with the correct credentials so not sure what's happening here. I'm using the codeigniter php framework.
I'm using Basic auth with:
var auth = 'Basic ' + btoa(username:password);
Here's the code:
let postDataSession = {
"purchase_country" : bookingData.purchase_country,
"purchase_currency" : bookingData.purchase_currency,
"locale" : bookingData.locale,
"order_amount" : bookingData.order_amount,
"order_tax_amount" : 0,
"order_lines" : [{
//"type" : "physical",
"reference" : bookingData.order_lines.reference,
"name" : bookingData.item_name,
"quantity" : 1,
"unit_price" : bookingData.order_amount,
"tax_rate" : 0,
"total_amount" : bookingData.order_amount,
"total_discount_amount": 0,
"total_tax_amount" : 0
}]
};
fetch('https://api.playground.klarna.com/payments/v1/sessions', {
method: 'POST',
//mode: 'no-cors',
//Authorization: auth,
headers: {
'Content-Type': 'application/json',
'Authorization': auth,
//'Access-Control-Allow-Credentials' : true,
'Access-Control-Allow-Headers' : 'pm-u, pm-h0, pm-h1, pm-h3, pm-o0, pm-o1, pm-o2, pm-o3, authorization',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Origin': 'https://localhost',
'ACCESS-CONTROL-MAX-AGE' : 3600,
'referrer-policy': 'no-referrer-when-downgrade'
},
body: JSON.stringify(postDataSession),
})
.then(function(response) {
//The following method initializes the Klarna Payments JS library
//window.location.href = baseurl + "customer/klarna_checkout_page";
if (!response.ok) {
return response.text().then(result => Promise.reject(new Error(result)));
console.log(response.status);
}
console.log(response.json(), response);
return response.json();
})
// .then(function(session) {
// window.location.href = baseurl + "customer/klarna_checkout_page";
// })
.then(function(result) {
// If `redirectToCheckout` fails due to a browser or network
// error, you should display the localized error message to your
// customer using `error.message`.
if (result.error) {
alert(result.error.message);
}
console.log(result);
})
.catch(function(error) {
console.error('Error:', error);
});
I've tried it the mode set to no-cors and receive the same response. I've used postman to post the request with the same data and in postman a response is received. Not sure if I'm either missing or overlooking something so a fresh perspective would be helpful. Does anyone have any idea how to proceed with resolving this issue? I want to avoid having to deploy this code to the live domain and be able to test the response on localhost, not sure if that's at all possible with cors.
Browser extensions are notoriously useless at dealing with preflighted requests. It won't help here.
No-cors mode makes the browser silently fail anything that requires CORS permission instead of throwing an exception. It won't help here.
Postman isn't a browser. It's requests aren't triggered by visiting a website. It doesn't implement the Same Origin Policy and doesn't need permission from CORS.
I'm getting a 401 Preflight which indicates unauthorized but I'm setting the Authorization header with the correct credentials so not sure what's happening here.
The browser is making a preflight request asking permission to send a POST request with credentials.
The server is getting the preflight request and complaining that it doesn't have credentials on it.
Either:
Change the server you are making the request to so it grants you permission in your development environment. It needs to allow OPTIONS requests without credentials on them.
Use a proxy that relays your requests to the server
Is your backend .net core web services? If so, I have seen this problem when you call UseCors after UseAuthentication in your pipeline. If you do that, you will need an authenticated token to do the preflight which is why you get a cors error throwing the exception. Move UseCors to before UseAuthentication so that a CORS response does not have to go through the Authentication middleware first.
I want to GET JSON from the endpoint https://api.brawlstars.com/v1/brawlers.
(https://api.brawlstars.com/v1/brawlers?Authorization="Bearer%20[My API Key]")
Here's my Code:
let url = 'https://api.brawlstars.com/v1/brawlers'
fetch(url, {
method: "GET",
headers: {
"Authorization": "Bearer **USER'S API KEY GOES HERE**"
}
}).then((response) => {
let json = response.json();
console.log(json);
}).catch((err) => {
console.error(err)
});
This is the output (error):
Access to fetch at 'https://api.brawlstars.com/v1/brawlers' from origin 'http://127.0.0.1:8887' has been
blocked by CORS policy: 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.
sketch.js:3 GET https://api.brawlstars.com/v1/brawlers net::ERR_FAILED
127.0.0.1/:1 Uncaught (in promise) TypeError: Failed to fetch
What am I missing?
In your header, you need to enable CORS like CBroe said :
headers.append('Access-Control-Allow-Origin', 'http://127.0.0.1:8887');
headers.append('Access-Control-Allow-Credentials', 'true');
Edit :
The server (that the POST request is sent to) needs to include the Access-Control-Allow-Headers header (etc) in its response. Putting them in your request from the client has no effect.
This is because it is up to the server to specify that it accepts cross-origin requests (and that it permits the Content-Type request header, and so on) – the client cannot decide for itself that a given server should allow CORS.
I am trying to access the header 'error-detail' as you can see in the browser network inspector (link above), the header gets returned. Server-wise I have also added the custom header to the 'Access-Control-Expose-Headers' to allow cross-domain requests as this was suggested to be the fix on other questions.
Below is the request to the server along with the success/error callbacks.
this.signon = function (request, onComplete, onError) {
console.log("Calling server with 'login' request...");
return $http.post("http://localhost:8080/markit-war/services/rest/UserService/login/", request)
.then(onComplete, onError);
};
var onLookupComplete = function(response) {
if (response.data.username)
{
//If user is returned, redirect to the dashboard.
$location.path('/dashboard');
}
$scope.username = response.data.username;
};
var onError = function(response) {
$scope.error = "Ooops, something went wrong..";
console.log('error-detail: ' + response.headers('error-detail'));
};
When I try access the response header as seen below:
console.log(response.headers());
console.log('error-detail: ' + response.headers('error-detail'));
This only outputs:
content-type: "application/json"
error-detail: null
Is there a reason why the error-detail header is not being mapped over to the response object?
I think you are on the right track. To have access to custom headers, your server needs to set this special Access-Control-Expose-Headers header, otherwise your browser will only allow access to 6 predefined header values as listed in the Mozilla docs.
In your screenshot such a header is not present in the response. You should have a look at the backend for this cors header to also be present in the response.
This is a CORS Issue. Because this is a cross-origin request, the browser is hiding most ot the headers. The server needs to include a Access-Control-Expose-Headers header in its response.
The Access-Control-Expose-Headers1 response header indicates which headers can be exposed as part of the response by listing their names.
By default, only the 6 simple response headers are exposed:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
If you want clients to be able to access other headers, you have to list them using the Access-Control-Expose-Headers header.
For more information, see MDN HTTP Header -- Access-Control-Expose-Headers
I'm trying to get a response from server. The function looks so:
function getOverview() {
var req = {
method: 'GET',
url: base,
headers: {
'authorization': 'Bearer ' + GottenTokens.getSessionToken()
}
};
return $http(req).then(
function successCallback(response) {
return response;
}, function errorCallback(response) {
console.log(response);
return response;
});
}
When the status is 200, there's no problem, it returns the good response with status 200. But... when the status is 401, than it returns a response with status -1:
Object {data: null, status: -1, config: Object, statusText: ""}
I was trying it in postman and I saw there's the status 401 and also in browser it says so:
XMLHttpRequest cannot load http://localhost:5000/overview. 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.
It means that the browser and postman take the status from server, but it doesn't come in Angularjs. I was trying this post: Capture Http 401 but it doesn't help me. I have that function in a "factory".
By the way, the server is written in akka. I don't know if it has something to do. Before was it in NodeJS and I didn't have problems. Since it's in akka I can't get the status in Angularjs.
Could anybody help me?
When doing cross-site requests, the server has to add to ALL responses a valid CORS header. This includes error responses like 401.
Make sure you can see the "Access-Control-Allow-Origin" header in your 401 response, it's most likely missing.
I'm trying to do an AJAX request to https://developers.zomato.com/api/v2.1/search referring to Zomato API
The server has headers:
"access-control-allow-methods": "GET, POST, DELETE, PUT, PATCH, OPTIONS",
"access-control-allow-origin": "*"
The problem is that the API requires additional headers set for user-key. But whenever I set custom headers then chrome would do a pre-flight request by sending an OPTIONS request to the above URL which is failing, and thus the AJAX request is failing as well.
If I don't set the headers, then I don't get a CORS error, but rather a forbidden error from server since I'm not setting user-key header.
Any way to go about this catch-22 situation?
Both Jquery and JavaScript way are failing:
$(document).ready(function () {
$.ajax({
url: 'https://developers.zomato.com/api/v2.1/search',
headers: {
'Accept': 'application/json',
'user_key': 'XXXXX'
},
success: function (data) {
console.log(data);
}
});
});
var xhr = new XMLHttpRequest();
var url = 'https://developers.zomato.com/api/v2.1/search';
xhr.open('GET', url, false);
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('user_key', 'XXXXXX');
xhr.send(null);
if (xhr.status == 200) {
console.log(xhr.responseText);
}
Error I'm getting:
OPTIONS https://developers.zomato.com/api/v2.1/search
XMLHttpRequest cannot load https://developers.zomato.com/api/v2.1/search. 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:8000' is therefore not allowed access. The response had HTTP status code 501.
If somebody wants to reproduce you can get a free user-key here:
https://developers.zomato.com/api
There does not appear to be a work-around for this issue from a browser. The CORS specification requires a browser to preflight the request with the OPTIONS request if any custom headers are required. And, when it does the OPTIONS preflight, it does not include your custom headers because part of what the OPTIONS request is for is to find out what custom headers are allowed to be sent on the request. So, the server is not supposed to require custom headers on the OPTIONS request if it wants this to work from a browser.
So, if the server is requiring the custom headers to be on the OPTIONS request, then the server is just expecting something that will not happen from a browser.
See related answers that describe more about this here:
jQuery CORS Content-type OPTIONS
Cross Domain AJAX preflighting failing Origin check
How do you send a custom header in a cross-domain (CORS) XMLHttpRequest?
Using CORS for Cross-Domain Ajax Requests
And, another user with the same issue here:
Zomato api with angular
It appears the Zomato is not browser friendly, but requires access from a server where you don't have CORS restrictions.
FYI, the error coming back from Zomato is 501 which means NOT IMPLEMENTED for the OPTIONS command. So, it looks like it's not only that the key is not being sent with the OPTIONS command, but that Zomato does not support the OPTIONS command, but that is required for the use of custom headers on a cross-origin request from a browser.
You can't bypass Access-Control-Allow-Headers in preflight response.
However as mentioned by #Jaromanda X in comments, Zomato sends:
Access-Control-Allow-Headers:X-Zomato-API-Key
...meaning you can only send this non-standard header from browser. Also don't go too low-level in request definition when jQuery has pretty and prepared shorthands ...
TL;DR Working example:
$.ajax({
type: "GET", //it's a GET request API
headers: {
'X-Zomato-API-Key': 'YOUR_API_KEY' //only allowed non-standard header
},
url: 'https://developers.zomato.com/api/v2.1/dailymenu', //what do you want
dataType: 'json', //wanted response data type - let jQuery handle the rest...
data: {
//could be directly in URL, but this is more pretty, clear and easier to edit
res_id: 'YOUR_RESTAURANT_OR_PLACE_ID',
},
processData: true, //data is an object => tells jQuery to construct URL params from it
success: function(data) {
console.log(data); //what to do with response data on success
}
});