The following code:
fetch('http://localhost:8080/root/1487171054127/k_query_bearer_token', {
mode: 'no-cors', credentials: 'include'
})
.then(function (response) {
return response.text();
})
.then(function (text) {
console.log('Request successful', text.length);
})
.catch(function (error) {
log('Request failed', error)
});
is outputting:
Request successful 0
If I use curl:
curl 'http://localhost:8080/root/1487171054127/k_query_bearer_token' \
-H 'Cookie: JSESSIONID=CviS9IK8pcsqADdP-m0MRXX_AvUqfzjJPwk1Yytf.ee16d0a01ad5'
I get a token in text form back (length != 0).
And if I output the response header via:
curl 'http://localhost:8080/root/1487171054127/k_query_bearer_token'
-H 'Cookie: JSESSIONID=CviS9IK8pcsqADdP-m0MRXX_AvUqfzjJPwk1Yytf.ee16d0a01ad5'
--head
I get:
HTTP/1.1 200 OK
Connection: keep-alive
X-Powered-By: Undertow/1
Server: JBoss-EAP/7
Content-Type: text/plain
Content-Length: 1730
Date: Wed, 15 Feb 2017 16:17:00 GMT
Why am I getting no text via fetch?
Remove mode: 'no-cors'.
When you use no-cors mode, you’re explicitly specifying that you want an “opaque response”.
Your script can’t access any properties of an opaque response—instead essentially all you can do is cache it. no-cors mode is basically useful only when doing caching with Service Workers.
If the reason you have your script using no-cors mode is because cross-origin requests to the server otherwise won’t work, the right solution is either to update the server-side code to send the Access-Control-Allow-Origin response header and other CORS headers—if you have access to the server do to that—or else, use a proxy like https://cors-anywhere.herokuapp.com/.
Related
I have some problems with sending a POST request to my REST-API.
The problem is, when I send it from a react application, it shows me this error in the debug console of firefox.
The funny thing is, that it works perfectly fine when sending the request with postman.
This is the code i use to make the request:
let apiURL = API_URL_BASE + "/api/authenticate"
let requestBody = JSON.stringify(
{
"username": this.getEnteredLoginUsername(),
"password": this.getEnteredLoginPassword()
}
);
let headerData = new Headers();
headerData.append('Accept', '*');
headerData.append("Access-Control-Allow", "*");
headerData.append('Content-Type', 'application/json');
headerData.append('Access-Control-Allow-Origin', '*');
headerData.append("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
headerData.append("Access-Control-Allow-Headers", "*");
let requestOptions = {
method: 'POST',
mode: 'cors',
redirect: 'follow',
body: requestBody,
headers: headerData
}
this.setState({loadingData: true});
fetch(apiURL, requestOptions).then( response => {
let responseStatus = response.status;
response.json().then( responseJSON => {
});
});
I hope someone can help me with this.
This is the error shown by firefox console: Image
You do seem to have a correct request header from the client-side, i.e the browser, but your server that is hosting the API must also send a response to the client back indicating that it allows cross-origin requests, Otherwise browser would not proceed ahead with your request. Setting cors headers from the server would depend on what framework you're using for the backend. In fact you need to add those cors header you've added here to the server code.
A sample response header would look like this :
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: * (Note: * means this will allow all domains to request to your server)
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
For express, you can follow this link.
More on CORS here
I'm trying to make a GET query using Fetch but I'm getting an error 404 when passing the Authorization.
I don't know why this error happens because the server responds well when I use a tool like Postman.
Authorization: Basic ...
method: GET
url: https://zammad.zonngo.com/api/v1/ticket_articles
When I use Javascript fetch API the error 404 appears.
OPTIONS https://zammad.zonngo.com/api/v1/ticket_articles 404 (Not Found)
There's my code:
const myHeaders = new Headers();
myHeaders.append('Authorization','Basic ...');
myHeaders.append('Content-Type','application/json');
fetch(URLTICKETS, {
method: 'GET',
headers: myHeaders
})
.then(response => {
console.log(response);
})
.then(error => {
console.log(error);
});
Would be nice if anyone can help me.
The GET method on the URL returns a 401 status code but the OPTIONS method actually returns a 404.
http OPTIONS https://zammad.zonngo.com/api/v1/ticket_articles
HTTP/1.1 404 Not Found
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 02 Nov 2017 01:37:59 GMT
Server: nginx/1.10.3 (Ubuntu)
Transfer-Encoding: chunked
X-Request-Id: 16f58319-2658-4b0e-824c-08ca68e8d401
X-Runtime: 0.003135
The OPTIONS is probably caused by a CORS preflight request which does not seem to be handled correctly by https://zammad.zonngo.com/.
https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
SO my graphql api is at https://gpbaculio-tributeapp.herokuapp.com/graphql I configured the uploaded, headers like this:
const fetchQuery = (operation, variables) => {
return fetch('/graphql', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({
query: operation.text,
variables,
}),
}).then(response => {
return response.json()
})
}
I have read from MDN.
For requests without credentials, the server may specify "*" as a
wildcard, thereby allowing any origin to access the resource.
So I am trying to publish the app in codepen, and this is my error:
Failed to load https://gpbaculio-tributeapp.herokuapp.com/graphql:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://s.codepen.io'
Why is it telling me it doesn't pass 'Access-Control-Allow-Origin' headers?
Is there something wrong with my headers config?
You are setting the header in your request (in the client). The Access-Control-Allow-Origin header needs to be set on the server-side, and when you make a request, the response should contain that header.
The reason behind this header is that not every webpage can query every third-party domain. Being able to set this header from the request would defeat that whole point.
Try setting cors options and Access-Control-Allow-Origin headers in server side.
const graphQLServer = express();
const corsOptions = {
origin(origin, callback) {
callback(null, true);
},
credentials: true
};
graphQLServer.use(cors(corsOptions));
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
graphQLServer.use(allowCrossDomain);
This may help you
CORS specification states, that requests for resources are "preflighted" with HTTP OPTIONS request, and reply headers for that OPTIONS must contain header:
Access-Control-Allow-Origin: *
you might check it with curl:
$ curl -I -X OPTIONS https://gpbaculio-tributeapp.herokuapp.com/graphql
HTTP/1.1 405 Method Not Allowed
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Allow: GET, POST
Content-Type: application/json; charset=utf-8
Content-Length: 97
Date: Sat, 23 Sep 2017 11:24:39 GMT
Via: 1.1 vegur
Add OPTION handler with needed header, so your server answers:
$ curl -I -X OPTIONS https://example.localhost/
HTTP/1.1 204 No Content
Server: nginx/1.4.7
Date: Sat, 23 Sep 2017 11:27:51 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range
Content-Type: text/plain; charset=utf-8
Content-Length: 0
The problem is the browser's cross-origin problem.
The Access-Control-Allow-Origin header should be return by the server's response, and the header means the origin domain that can access to the API.
The client's request often take a header Origin, it's value is the current host address, like, www.example.com.
The values of Access-Control-Allow-Origin must contain the value of Origin means that the origin can access this API service. And then the browser will continue the request. If not, the browser will cancel the request.
More infomation, refre to CORS https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
I am trying to make a http get request from AngularJS. It is only working in the Internet Explorer 11. When I try to make a POST Call in Chrome, Firefox or Edge it is not working.
I get the following error:
CORS Error in Chrome
This is my AngularJS Call:
$http({
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
url: URL
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
console.log(response.status);
console.log(response.headers);
console.log(response.config);
});
As backend I have a Java Spring MVC Application and I have set the following headers:
HttpHeaders responseHeader = new HttpHeaders();
responseHeader.set("Access-Control-Allow-Origin","*");
responseHeader.set("Access-Control-Allow-Headers:","Content-Type");
responseHeader.set("Access-Control-Allow-Methods","POST, GET, PUT, OPTIONS, DELETE");
responseHeader.set("Content-Type","application/json");
But I saw that angular never reaches the backend when I set a breakpoint! This is very confusing, I already searched a lot in the internet and tried to changed the default AngularJS Content-Type header:
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
I tried also to change the Content-Type in the POST-Request to "application/x-www-form-urlencoded" - with no effect.
Note: The backend and the frontend runs on the same dev machine. The only difference is the port, that's why I am confused that I get a CORS Error at all...
I have this problem only with POST-Requests; GET works like a Charm
Edit 1:
I thought that this is a Problem with cors and that i use different ports, but is it possible that I can turn that off?
Edit 2:
Now i try to get it to work with a local tomcat. Now i see in the Tomcat the request will reach the server:
<< Client IP>> - - [28/Jun/2017:13:43:24 +0200] "OPTIONS <<URL>> HTTP/1.1" 403 -
The Response is now HTTP 403. In Browsers network tab i can see the following request header:
Host: <<backend ip>>:8080
User-Agent: <<user agent>>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: access-control-allow-origin,content-type
Origin: http://<<Ip of host>>
Connection: keep-alive
The Response of that request header is the following:
Content-Type: text/plain
Content-Length: 0
Date: Wed, 28 Jun 2017 11:43:24 GMT
I have set the cors filter like the example in the tomcat documentation: http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter
When i make a get request, it is still working and all CORS headers are present.
I think there is something wrong with the first OPTIONS request. I dont know why the tomcat do not set the CORS header when the OPTIONS request comes.
In your Spring Controller, add #CrossOrigin('http://localhost:8080')
annotation. Of course, substitute out the port of your angular application.
Since you are getting 400 (not authorized) error, the request is not reaching the service itself. Most probably the request domain is blocked, you may see if XHR requests are allowed and check cross origin policy if needed.
I figured it out. I made a completly new angularjs testwebsite. This is my working angularjs Code:
var req = {
method: 'POST',
url: 'myURL',
headers: {
'Content-Type': undefined
},
data: "JSON BODY DATA"
}
$http(req).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
console.log(response.data);
});
}]);
I deleted anything that changed the default angularjs headers.
The headers of my Spring MVC Application are the following:
HttpHeaders responseHeader = new HttpHeaders();
responseHeader.set("Access-Control-Allow-Origin","http://<<clientip>>");
responseHeader.set("Access-Control-Allow-Headers:","Content-Type");
responseHeader.set("Access-Control-Allow-Methods","POST, GET, PUT, OPTIONS, DELETE");
responseHeader.set("Content-Type","application/json");
I dont know the exactly cause why it is working now. Maybe it was because i modified the default headers in AngularJS.
Okay, I've looked all over for this. Basically we're using $http request that ARE cross domain requests. Our server allows the domain and when a request returns 200, everything is OK. However, anytime our server returns an error, 500, 401, whatever, Angular thinks it's a CORS issue.
I debugged the response with Fiddler to verify my server IS returning a 500, yet Angular chokes on it.
Here's the request:
var params = {
url: "fakehost/example",
method: 'GET',
headers: {
"Authorization": "Basic encodedAuthExample"
}
};
$http(params).then(
function (response) { // success
},
function (error) { // error
// error.status is always 0, never includes data error msg
});
Then in the console, I will see this:
XMLHttpRequest cannot load fakehost/example. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'mylocalhost:5750' is therefore not allowed access.
Yet, in fiddler, the true response is:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 26 Aug 2014 12:18:17 GMT
Content-Length: 5683
{"errorId":null,"errorMessage":"Index was outside the bounds of the array.","errorDescription":"Stack trace here"}
I'm on AngularJS v1.2.16
I think I found an answer, looks like you will have to inject in your asp.net pipeline the correct CORS headers, as mentioned here.