1

I'm stumped. I'm trying to make a simple customer lookup request by first name. Both jQuery.ajax() (from the console) and Angular's $http.get() error out, but I don't know why. When I open in another tab the same URL given to those functions, it displays the expected JSON response.

jQuery

$.ajax("http://[ip#]:8081/customerservice/customer/search?firstName=John", {
  "dataType": "json",
  "success": function() {
    alert("success");
    console.log("jQuery data", data);
  },
  "error": function(jqXHR, textStatus, errorThrown) {
    alert("error");
    console.log("jQuery jqXHR", jqXHR);
    console.log("jQuery textStatus", textStatus);
    console.log("jQuery errorThrown", errorThrown);
  },
  "complete": function(jqXHR, textStatus) {
    alert("complete");
    console.log("jQuery jqXHR", jqXHR);
    console.log("jQuery textStatus", textStatus);
  }
});

result: The error and complete alerts fire. textStatus is "error", errorThrown is an empty string, jqXHR contains

readyState    0
responseText  ""
status        0
statusText    "error"

Angular

return $http.get('http://[ip#]:8081/customerservice/customer/search?firstName=John',
    {
        responseType: "json"
    }
)
.success(function(data, status, headers, config){
    alert("angular success");
})
.error(function(data, status, headers, config){
    alert("angular error");
    console.log(status);
    console.log(headers());
    console.log(config);
})
;

result I see a "200 OK" and response time in Firebug with the given URL. status is 404, headers() returns an empty object, and the config object is

headers           Object { Accept="application/json, text/plain, */*"}
Accept            "application/json, text/plain, */*"
method            "GET"
responseType      "json"
transformRequest  [function()]
    0
    function()
transformResponse [function()]
    0
    function()
url               "http://[ip#]:8081/customerservice/customer/search?firstName=John"

Firebug also shows

Response Headers
Content-Type    application/json
Date    Sat, 15 Feb 2014 05:13:02 GMT
Server  Apache-Coyote/1.1
Transfer-Encoding   chunked

Request Headers
Accept  application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
DNT 1
Host    [ip#]:8081
Origin  http://127.0.0.1
Referer http://127.0.0.1/
User-Agent  Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0

other info I'm running this in a VM, though I'm still able to access the Internet at large, and [ip#] directly. I'm new to Angular, which is why I tried it with jQuery.

So, what's going on? I built this off the Angular UI Typeahead example, and it worked fine with the Google geocode URL. Is it because I'm using an IP# and/or port? Is it something glaring that I just don't see?

Update: The CORS headers have been added, and jQuery now works, but Angular is giving 404s. It seems the sent-by-default X-Requested-With header was a problem with CORS in 1.1, but I'm using 1.2.

jQuery

$.post(
    "http://[ip#]:8081/customerservice/customer/search",
    "firstName=John&lastName=Smith",
    function (data, textStatus, jqXHR) {
      console.log("success!", data);
    }
);

Angular

$http.post("http://[ip#]:8081/customerservice/customer/search",
        "firstName=John&lastName=Smith"
    )
    .success(function(data, status, headers, config) {
        $scope.result = data;
    })
    .error(function(data, status, headers, config) {
        $scope.result = data || "Request failed";
        console.log("status: ", status);
        console.log("headers: ", headers());
        console.log("config: ", config);
    })
;
Community
  • 1
  • 1
nshew13
  • 3,052
  • 5
  • 25
  • 39
  • 2
    looks like a same origin policy violation issue... whether the page and the resource are in the dame domain? – Arun P Johny Feb 15 '14 at 05:20
  • yep, definitely a CORS issue. you will need to make changes to your server to the allow-origin and allow-headers settings. The browsers are preflighting your request, and determining that what your xHr settings are configured to send, vs what the endpoint is configured to receive. – Brian Vanderbusch Feb 15 '14 at 07:18
  • That's got to be it. If one of you will submit an answer, I'll accept after I can get the server updated to confirm. – nshew13 Feb 16 '14 at 05:13

1 Answers1

0

As Arun P Johny and Brian Vanderbusch pointed out, it was a CORS issue.

Adding the Access-Control-Allow-Origin header allowed the jQuery response to start working.

However, "the $http service will automatically add certain HTTP headers to all requests" ["Setting HTTP Headers", AngularJS docs]. In this case, it was a Content-Type header, and it caused another CORS issue: OPTIONS ... Request header field Content-Type is not allowed by Access-Control-Allow-Headers.

This did not show up in Firebug nor Firefox's Console. It wasn't until I tried Chrome that I got any output to help debug.

The solution is to:

  1. Add Content-Type to Access-Control-Allow-Headers (see note), or
  2. Delete the default Content-Type header from the request, similar to this answer.

    myApp.config(function($httpProvider){
        delete $httpProvider.defaults.headers.post['Content-Type'];
    });
    

Note: My fellow dev had specified Access-Control-Allow-Headers of x-requested-with, so I don't know if that single entry negates all others, or if Content-Type needs to be specified either way.

Community
  • 1
  • 1
nshew13
  • 3,052
  • 5
  • 25
  • 39