gshock
gshock

Reputation: 711

Missing headers in response for jQuery request with CORS

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 enter image description here 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

Answers (2)

gshock
gshock

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

Chilian
Chilian

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

Related Questions