I have an http request where I want some response headers that are, for one reason or another, unavailable to me from the response object but visible in the chrome dev tools
But the response object from the javascript request api only contains some of these headers.
{ // response.headers
cache-control: "no-cache, private",
content-type: "application/json"
}
Surely, there must be a way to get things like x-ratelimit-limit as part of the response. If it's information sent to the browser, why can't it be available in a javascript http request api?
This looks like a CORS request. If so, response headers are restricted unless the right Access-Control-Allow-Headers header is set. This is for security reasons.
Related
We've created one EXE file using the CPP language and create one API like http://localhost:5800/get-id/. when I open in browser return me the perfect output.
When I used fetch in HTML > script page, then getting No "Access-Control-Allow-Origin" header is present on the requested resource.
Code1:
fetch("http://localhost:5800/get-id/", {method: 'GET').then(function(response) {
console.log(response.text());
}).catch(function(error) {
console.log('Request failed', error)
});
After research, I've added the mode: no-cors error lost but getting an empty response.
Code2:
fetch("http://localhost:5800/get-id/", {method: 'GET', mode: 'no-cors'}).then(function(response) {
console.log(response.text());
}).catch(function(error) {
console.log('Request failed', error)
});
If I use code2 in any inspect console then getting an empty body but when I open http://localhost:5800/get-id/ in the browser and try to hit code2 in the console then getting the perfect parameter.
It means, localhost domain it's working fine but when it's fetched from any domain through my error.
What is the proper solution for it? In C/CPP language how can we allow cors?
Strange:
when I hit from console, it's show me empty
For same request I checked network tab, show 200 OK with proper response / preview data
CORS is a complex topic, I usually use CORS middleware to handle it in Node.JS in Express server (maybe the code will be useful to solve this).
It's goal is to allow API on domain api-domain to list web applications that can use it, for example your application is on webapp-domain domain.
When application calls fetch('http://api-domain/get-id/') to another domain it is referred to as cross-origin call.
All browser do CORS preflight call like this to check for allowance:
OPTIONS /get-id/
Access-Control-Request-Method: GET
Access-Control-Request-Headers: origin, x-requested-with
Origin: http://webapp-domain
(please note it's an OPTION request to the API, not GET)
And response should list webapp-domain as allowed (and specify which HTTP methods are allowed)
HTTP/1.1 204 No Content
Connection: keep-alive
Access-Control-Allow-Origin: http://webapp-domain
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400
After the successful preflight call like this the browser will continue with fetch, for example, it will send GET request to http://api-domain/get-id/
P.S.
One of the ways to skip CORS is to set HTTP proxy in webapp-domain which will call api-domain on server-side and is not limited by CORS. See this answer for details.
I am calling an API from different domain, it doesn't have any authorization check for now but in future we are planning to do so. When I hit this API without any headers I get the response but when I set the headers the browser throws CORS error. the headers are appID, version and empID. "Access-Control-Allow-Origin" header is set on server side. I am using another API from another domain which works perfectly fine with and without headers. I think the issue is with content-type or data-type but I am clueless.I get the response in JSON format.
When you pass non-standard headers to an AJAX request, the client will send a pre-flight OPTIONS HTTP Request before attempting the real request.
Your server needs to be able to handle that request, and also return the required ACAO headers in response to it.
logout(){
var destroySession='{"token":"'+this.token+'"}'
console.log("Session Destroy"+destroySession)
axios.post(eventBus.apiURL+'logout',{
headers: {
'Content-type': 'application/json',
},
body: destroySession,
}).then(response=>{
console.log("RESadas :: "+JSON.stringify(response.data))
alert("Logout successfully..!")
this.$router.push('/')
},error=>{
console.log(error);
alert("Some Issue for LogOut at Server Side..!")
});
window.localStorage.removeItem('token')
window.localStorage.removeItem('name')
this.$router.push('/')
}
<button #click="logout">Logout</button>
I have written a code for logout in vuejs, but at the time of click it sends two POST request and during session destroy problem occurs at server side.
As per Mozilla Developer Network,
Preflight Requests
Unlike “simple requests” (discussed above), "preflighted" requests
first send an HTTP request by the OPTIONS method to the resource on
the other domain, in order to determine whether the actual request is
safe to send. Cross-site requests are preflighted like this since they
may have implications to user data.
In particular, a request is preflighted if any of the following
conditions is true:
If the request uses any of the following methods:
Put
DELETE
CONNECT
OPTIONS
TRACE
PATCH
Or if, apart from the headers set automatically by
the user agent (for example, Connection, User-Agent, or any of the
other header with a name defined in the Fetch spec as a “forbidden
header name”), the request includes any headers other than those which
the Fetch spec defines as being a “CORS-safelisted request-header”,
which are the following:
Accept
Accept-Language
Content-Language
Content-Type (but note the additional requirements below)
DPR
Downlink
Save-Data
Viewport-Width
Width
Or if the Content-Type header has a
value other than the following:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Updated
Please read this answer on how to disable preflight requests: Link
This question already has answers here:
Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not?
(13 answers)
Closed 6 years ago.
I Have Service which is having the url of another computer, I am getting this error while accessing the response from my other computer using the Ip address..
$http({method : 'post',
url : 'http://xxx.xxx.0.xxx:8080/hms/spring/user/users'
data : ''}).then(function(response) {
$scope.patient_data = response.data;
});
Getting this error:
XMLHttpRequest cannot load http://xxx.xxx.0.xxx:8080/hms/spring/user/users. 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:8080' is therefore not allowed access.
Access-Control-Allow-Origin is a CORS (Cross-Origin Resource Sharing) header.
When Site A tries to fetch content from Site B, Site B can send an Access-Control-Allow-Origin response header to tell the browser that the content of this page is accessible to certain origins. (An origin is a domain, plus a scheme and port number.) By default, Site B's pages are not accessible to any other origin; using the Access-Control-Allow-Origin header opens a door for cross-origin access by specific requesting origins.
For each resource/page that Site B wants to make accessible to Site A, Site B should serve its pages with the response header:
Access-Control-Allow-Origin: http://siteA.com
Modern browsers will not block cross-domain requests outright. If Site A requests a page from Site B, the browser will actually fetch the requested page on the network level and check if the response headers list Site A as a permitted requester domain. If Site B has not indicated that Site A is allowed to access this page, the browser will trigger the XMLHttpRequest's error event and deny the response data to the requesting JavaScript code.
Non-simple requests:
What happens on the network level can be slightly more complex than explained above. If the request is a "non-simple" request, the browser first sends a data-less "preflight" OPTIONS request, to verify that the server will accept the request. A request is non-simple when either (or both):
using an HTTP verb other than GET or POST (e.g. PUT, DELETE) using non-simple request headers; the only simple requests headers are: Accept Accept-Language Content-Language Content-Type (this is only simple when its value is application/x-www-form-urlencoded, multipart/form-data, or text/plain) If the server responds to the OPTIONS preflight with appropriate response headers (Access-Control-Allow-Headers for non-simple headers, Access-Control-Allow-Methods for non-simple verbs) that match the non-simple verb and/or non-simple headers, then the browser sends the actual request.
Supposing that Site A wants to send a PUT request for /somePage, with a non-simple Content-Type value of application/json, the browser would first send a preflight request:
OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
Note that Access-Control-Request-Method and Access-Control-Request-Headers are added by the browser automatically; you do not need to add them. This OPTIONS preflight gets the successful response headers
Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
When sending the actual request (after preflight is done), the behavior is identical to how a simple request is handled. In other words, a non-simple request whose preflight is successful is treated the same as a simple request (i.e., the server must still send Access-Control-Allow-Origin again for the actual response).
The browsers sends the actual request:
PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json
{ "myRequestContent": "JSON is so great" }
And the server sends back an Access-Control-Allow-Origin, just as it would for a simple request:
Access-Control-Allow-Origin: http://siteA.com
See Understanding XMLHttpRequest over CORS for a little more information about non-simple requests.
I believe it would help you to understand CORS issue and resolution better.
I need to add some common extra info (needs to be sent with most of our http requests) to cross domain http requests, the extra data is something like device info or location info. We are using custom http headers for these info currently, but the custom header will make the browser to send an preflight request before the real http request, so we want to remove the preflight request for performance considerations. We considered using cookie firstly, but since the request is cross-domain, we can't set cookie for the domain of our API with javascript. Then I searched for documents, According to Mozilla docs:
In particular, a request is preflighted if:
It uses methods other than GET, HEAD or POST. Also, if POST is used
to send request data with a Content-Type other than
application/x-www-form-urlencoded, multipart/form-data, or text/plain,
e.g. if the POST request sends an XML payload to the server using
application/xml or text/xml, then the request is preflighted.
It sets custom headers in the request (e.g. the request uses a header
such as X-PINGOTHER)
So I thought if I use a standard http header which is seldom used: the "From" header, it will not trigger the options request. but after I test this, I found I was wrong, the "From" header still trigger the options request.
So I have two questions:
Why does a standard http header trigger the preflight request?
How should I send the extra info without trigger the preflight request?
Any helps will be appreciated.
Read the above portion of the same page on what constitutes a "simple request" that doesn't need to be preflighted:
Apart from the headers set automatically by the user-agent (e.g. Connection, User-Agent, etc.), the only headers which are allowed to be set manually are
Accept
Accept-Language
Content-Language
Content-Type
"custom headers" doesn't mean "nonstandard headers", it means any header not automatically set by the browser, other than those four.