-2

I am trying to GET information from this site https://bitcoinindex.es/api/v0.1/coinbase/usd/btc/last

Using the $http service

After looking all over the internet Here is my code in coffeescript

angular.module('blackmoonApp')
  .controller 'PricingCtrl', ($scope, $http) ->
    $http.defaults.useXDomain = true
    $http.get("https://bitcoinindex.es/api/v0.1/coinbase/usd/btc/last",
      headers:
        "Access-Control-Allow-Origin": "*"
    ).success (JSON) ->
      console.log JSON

The Result is

"XMLHttpRequest cannot load https://www.bitstamp.net/api/ticker/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access."

I am not sure if the website is blocking me (which wouldn't make sense because it is an API) or if AngularJS isn't able to work with CORS.

grasshopper
  • 918
  • 4
  • 13
  • 29

2 Answers2

2

Access-Control-Allow-Origin is a response header.

This:

  headers:
    "Access-Control-Allow-Origin": "*"

… sets a request header.

You need to set it on https://www.bitstamp.net/api/ticker/, not in your JavaScript.

It would defeat the object if any JavaScript could grant itself permission to access any server.


I am not sure if the website is blocking me (which wouldn't make sense because it is an API)

Blocking is the default behaviour. Explicit permission must be granted to allow JavaScript from other origins access. Otherwise anyone with a bitstamp account could have their bitcoins stolen by visiting a website that used the API (since it would be their browser, with their cookies, making the request).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

From your code:

$http.get("https://www.bitstamp.net/api/ticker/",
  headers:
    "Access-Control-Allow-Origin": "*"
)

We see that you are attempting to send the Access-Control-Allow-Origin header in the GET request.

CORS doesn't work that way; the Access-Control-Allow-Origin header must be present in the response sent by the server (and, of course, such header must include the exact same domain of the page that sent the request).

From my tests (unlikely, but your results may differ):

  • https://bitcoinindex.es/api/v0.1/coinbase/usd/btc/last only allows CORS requests from its own domain (the response had Access-Control-Allow-Origin:https://bitcoinindex.es) which is kind of pointless; and
  • https://www.bitstamp.net/api/ticker/ didn't have the Access-Control-Allow-Origin header at all.
Community
  • 1
  • 1
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • I don't understand what you mean. Can you rephrase? -- Look, for you to be able to make an Ajax request to a service at `https://bitcoinindex.es/`, either the HTML page that makes the request is deployed at `https://bitcoinindex.es/` or, if it is deployed somewhere else (say, http://www.grasshopper.com), then `https://bitcoinindex.es/` must include in its response `Access-Control-Allow-Origin: http://www.grasshopper.com`. As it is currently not including anything in that header, the browser is giving you that error. – acdcjunior Sep 26 '14 at 20:47
  • So its just a coincidence every API I'm trying doesn't have the header? This one works for me using Curl w/php, but same error with $http. http://data.bter.com/api/1/marketlist – grasshopper Sep 26 '14 at 20:49
  • No, not a coincidence. They simply didn't want to allow CORS requests to be made. Observe that you still can use the API/service, just not through a browser with the same-origin policy active (which is the default). Either you use other language, say Java/C#, or server-side JavaScript, or, if you still want to use a browser, you can disable the security check for CORS, but beware the page will only work in those browsers where you disable the security check (in other words, it will not work for the regular users around the internet). – acdcjunior Sep 26 '14 at 20:52
  • Or, of course, you can ask the owner of the `https://bitcoinindex.es/` API to include the `Access-Control-Allow-Origin` header for your domain. – acdcjunior Sep 26 '14 at 20:53
  • So have to call it through php, then return it to through CORS to my javascript right? – grasshopper Sep 26 '14 at 20:57
  • Right, almost. You can call it through PHP (at, say, `http://www.grasshopper.com/bitcoinindexMirror.php`) and make your HTML page that makes the Ajax request (say `http://www.grasshopper.com/index.php`) use the service at `bitcoinindexMirror.php` and not `https://bitcoinindex.es/` directly. This way, the request is just a regular Ajax, not a CORS, as both pages will be at the same domain (in the example, `http://www.grasshopper.com/`). – acdcjunior Sep 26 '14 at 21:01
  • You can create the mirror in PHP like this: https://gist.github.com/acdcjunior/e08c5a35cbc0f6e9f131 . And then your angular code could be: `$http.get("http://yourdomain.com/bitcoinindexMirror.php", ...`. – acdcjunior Sep 26 '14 at 21:07