Reputation: 711
I'm trying to execute CORS request with jquery buy I'm getting strange behaviour. When I use curl to execute the request everything is working fine. But when I use jQuery the things goes horribly wrong. In the "Network" tab in my browser I can inspect the request and the response from the back-end there everything is correct but although I have Access-Control-Expose-Headers: Set-Cookie header I get null when I try to print it out using console.log(response.getResponseHeader("Set-Cookie")); When I try to print out the response headers of my ajax request in the console with console.log(response.getAllResponseHeaders()) I get only these 3 headers:
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
The code that I'm using to execute requests is:
$.ajax({
method: "POST",
url: "http://localhost:8808/storage/login",
data: {
username: email,
password: password,
},
success: function(data, textStatus, response){
console.log(response.getAllResponseHeaders());
console.log(response.getResponseHeader("Set-Cookie"));
this.setState({showAlert: true, alertMessage: "You are logged in.", alertType: "success"});
}.bind(this),
error: function (xhr, status, err) {
this.setState({showAlert: true, alertMessage: "Wrong email or password", alertType: "danger"});
}.bind(this)
});
Upvotes: 8
Views: 5668
Reputation: 711
I have found the solution.
On server side add these headers on the response:
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With
Access-Control-Allow-Credentials: true
Access-Control-Allow-Credentials: true This is the important one. But you can not use Access-Control-Allow-Origin: * with it ! You must specify specific domain like Access-Control-Allow-Origin: http://example.com)
On client side update the ajax request to the following:
$.ajax({
method: "POST",
url: "http://localhost:8808/storage/login",
data: {
username: email,
password: password,
},
xhrFields: {
withCredentials: true
},
crossDomain: true,
success: function(data, textStatus, response){
console.log(response.getAllResponseHeaders());
console.log(response.getResponseHeader("Set-Cookie"));
this.setState({showAlert: true, alertMessage: "You are logged in.", alertType: "success"});
}.bind(this),
error: function (xhr, status, err) {
this.setState({showAlert: true, alertMessage: "Wrong email or password", alertType: "danger"});
}.bind(this)
});
The important part here is xhrFields: {withCredentials: true}, crossDomain: true. For more information see how to Set-Cookie on Browser with Ajax Request via CORS and after that Sending credentials with cross-domain posts? using jQuery
Actually you can not access the Set-Cookie header with response.getResponseHeader("Set-Cookie") so your console.log() will print every time null. You can find why here: $http response Set-Cookie not accessible but you can inspect the cookies of the current page and check that they are set correctly.
note: The requesting url must be HTTPS too for best answer.
Upvotes: 5
Reputation: 1347
Are you making a cross domain request?
http://www.html5rocks.com/en/tutorials/cors/ :
During a CORS request, the getResponseHeader() method can only access simple response headers. Simple response headers are defined as follows:
- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
If you want clients to be able to access other headers, you have to use the Access-Control-Expose-Headers header. The value of this header is a comma-delimited list of response headers you want to expose to the client.
Upvotes: 13