1

For some reason this:

return jquery.ajax('my url', {
    crossDomain : true
  , data : JSON.stringify({"brand": self.current})
  , type : 'POST'
  }).success(function(data){
    scope.results = data;
  });

and/or this:

curl -X POST -H "Content-Type: application/json" -d '{"brand":"target"}' myUrl

work fine, but this:

var req = {
  method: "POST"
, url : "my url"
, data : JSON.stringify({"brand": self.current})
};

return $http(req).
  success(function(data){
    scope.results = data;
});

fails miserably with

"OPTIONS my url (anonymous function) @ angular.js:9866sendReq @ angular.js:9667$get.serverRequest @ angular.js:9383processQueue @ angular.js:13248(anonymous function) @ angular.js:13264$get.Scope.$eval @ angular.js:14466$get.Scope.$digest @ angular.js:14282$get.Scope.$apply @ angular.js:14571(anonymous function) @ angular.js:21571jQuery.event.dispatch @ jquery.js:4430jQuery.event.add.elemData.handle @ jquery.js:4116

(index):1 XMLHttpRequest cannot load my url. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access. The response had HTTP status code 404."


They're the same url. Wtf. I have a sneaking suspicion that the "crossDomain : true" option in jquery is why the jquery one works, but if that's the case, then the question is:

how do I do that with angular?

-- When using jquery's default ajax method, the scope isn't updating with the results, but i know the data is being assigned because i'm logging it out, and if i submit the request again, the scope does update with the second value.

Second question- why isn't my view updating with the results?


update:

The reason this is failing has nothing to do with the response I'm getting back from the server, the problem is that Angular is transforming this POST request into an OPTIONS request: (taken from google chromes' xhr tool:)

Remote Address: the remote address
Request URL:the request endpoint
Request Method:OPTIONS <-------------
Status Code:404 Not Found

Further inspection reveals:

OPTIONS /my url HTTP/1.1 <--------------
Host: my urls host
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:5000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36
Access-Control-Request-Headers: accept, charset, content-type
Accept: */*
Referer: http://localhost:5000/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

which is not what it should be doing because I'm specifically saying in the req object i'm passing to $http that this is a POST request.

...

So how do I make angular... NOT do that?

also- why is it doing that?

3
  • 1
    The answer to the second question is: You need to call $scope.$apply() because angular doesn't know about stuff that happens in jquery. Commented Apr 20, 2015 at 2:13
  • If they are the same url, could you try removing localhost:5000/end_point and add only '/end_point' Commented Apr 20, 2015 at 2:56
  • @AtaurRahimChowdhury it's a cross-origin request. I'm developing locally but the service call is a website i don't own. Commented Apr 20, 2015 at 3:21

1 Answer 1

1

When you do a cross-origin request from your browser, all browsers hit the URL (provided in AJAX call) to confirm if the cross-origin request is available or not which is known as preflight request. https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

So, your server's endpoint must allow the preflight request in order to make this call work by setting some response headers like (an example in Groovy):

response.setHeader "Access-Control-Allow-Headers", "Content-Type"
response.setHeader "Access-Control-Allow-Methods", "POST,DELETE,PUT"
response.setHeader "Access-Control-Allow-Origin", "*"
Sign up to request clarification or add additional context in comments.

4 Comments

That's actually not the problem in this case- the server would be sending the correct response but Angular is transforming the request into an OPTIONS request, rather than a POST request.
Also- your solution wouldnt solve the problem because you didnt include "OPTIONS" in your Access-Control-Allow-Methods
Angular is doing this as a security precaution whereas jQuery does not. By setting your server to "Access-Control-Allow-Origin", "*", you are telling the server to allow any content headers which will in turn allow your $http.post to work. CORS is one of the little surprises you find when you start doing http calls across domains with Angular.
I think, OPTIONS method is allowed by default so it is working in my case (in a Grails based application). It might, your server does not allow that method by default, so adding it to allowed methods should solve one of those problems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.