2

I am using Request Bin to post some data. In my controller, I have the following code:

$http.post('http://requestb.in/redacted', fooBar).
    success(function(data) {
        $scope.fooBarPostedSuccess = true;
    }).
    error(function(err) {
        console.log("Error while posting to Request Bin");
        console.log("Error Info : " + err);
    });

This is triggered by means on a button on the UI. Now when this gets triggered, the data is not posted to Request Bin and I get this error:

XMLHttpRequest cannot load http://requestb.in/redacted.
Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.

How do I post data to request bin through an AngularJS controller? Also, what does the above error mean?

EDIT : I wish to add here that I am using Node.js with AngularJS. Is this something to do with Node perhaps?

callmekatootie
  • 10,989
  • 15
  • 69
  • 104

3 Answers3

3

Ah yes... you are dealing with cross-domain scripting issues. This is not an AngularJS problem, but a browser security limitation and a VERY common friction point.

You cannot POST/PUT/DELETE to another domain (different from the one which is hosting -- localhost in your case) without doing some Cross-Origin Resource Sharing (CORS). You are limited to GET for a cross-domain HTTP request.

You have two options:

  1. See if your API supports any cross-domain capabilities. This might be via CORS or it might be via an overloaded GET API or JSONP.

  2. Proxy requests through your server. Since you are using Node.js, proxying REST through your server is extremely simple... you just need to set up a route handler (like /api/redacted) in your Node.js server and then make a new request to your actual API server with something like Restler (NPM package) and return the result back to your client.

Hope this helps!

EDIT:

Your API supports JSONP (Your API Docs). You should be able to use Angular's JSONP function to access your API's JSONP capabilities. (Angular.js JSONP docs).

Since you want to be able to POST to the service, you will need to use the second approach.

Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
  • Sadly neither worked - as I understand, jsonp [cannot be used for POST requests](http://stackoverflow.com/a/3860117/2104976). The latter too did not work - I think I did it incorrectly. Is there a blog which shows how to make POST requests to external websites in node that you recommend? – callmekatootie Apr 16 '13 at 06:05
  • Right. You can only POST to another server using CORS if the server allows it. JSONP is really just GET under the hood. But if your API supports it, then you don't need to pust. You use `$http.jsonp`. – Brian Genisio Apr 16 '13 at 16:35
  • Proxying through node... here is a SO question about it: http://stackoverflow.com/questions/10166277/proxy-http-request-with-node – Brian Genisio Apr 16 '13 at 16:36
  • 1
    Also, I wrote an example of proxying REST calls to a Parse.com API on this blog post: http://houseofbilz.com/archives/2011/11/07/a-proxy-server-for-parse-com/ – Brian Genisio Apr 16 '13 at 16:38
  • Thanks - I do not know coffeescript but I realized that you are using Restler module and went through their documentation. Worked like a charm. Many thanks for pointing me in the right direction. Could you suggest this as answer - will mark it correct. – callmekatootie Apr 18 '13 at 07:22
1

CORS allows both GET and POST

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

http://www.w3.org/TR/cors/

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

Now, that that's out of the way... I too have found that angular's $http won't let me POST cross domain. I was suspicious about that though because I have jquery ajax calls in other projects that can post cross domain just fine. So, I swapped my $http POST with $.ajax POST and that worked.

// $http({
//  url: url,
//  method: "POST",
//  data: data
// })
// .success(successCallback)
// .error(errorCallback)

// ole reliable
$.ajax({
  type : "POST",
  url : url,
  data : data,
  success : successCallback,
  error : errorCallback,
  cache : false,
  dataType : 'json',
})
CodeWarrior
  • 332
  • 3
  • 9
0

You can use PutsReq instead of RequestBin. PutsReq supports CORS.

Pablo Cantero
  • 6,239
  • 4
  • 33
  • 44