2

How do you get data from a REST API with JavaScript. I have several basic API's that I would like to get data from that don't require any authentication. All of the API's return the data I want back in JSON. For example https://www.codewars.com/api/v1/users/MrAutoIt. I thought this would be a very simple process using xmlhttprequest but it appears the same-origin policy is giving me problems.

I have tried following several tutorials but they don’t seem to work on cross domains or I don’t understand them. I tried to post links to the tutorials but I don't have a high enough reputation on here yet.

MrAutoIt
  • 772
  • 4
  • 20
  • You should post sample code for what you tried. Your question is too open ended and vague. – T_Conroy Nov 11 '15 at 01:27
  • Assuming you don't control the APIs' servers, and they don't allow CORS, you really can't do much. One possibility, though extreme, would be to setup a reverse proxy server for that API. ([This answer could help.](http://stackoverflow.com/questions/19821753/jquery-xml-error-no-access-control-allow-origin-header-is-present-on-the-req/19821851#19821851)) – acdcjunior Nov 11 '15 at 01:29
  • How can you tell if they allow CORS? The only good website I could find on CORS is this: http://www.html5rocks.com/en/tutorials/cors. I could not find anything on how to determine if the website allows CORS. – MrAutoIt Nov 11 '15 at 13:39

4 Answers4

3

If you are trying to access a web service that is not on the same host:port as the webpage that is issuing the request, you will bump into the same origin policy. There are several things you can do, but all of them require the owner of the service to do things for you.

1) Since same origin policy does not impact scripts, allow the service to respond by JSONP instead of JSON; or

2) Send Access-Control-Allow-Origin header in the web service response that grants your webpage access

If you cannot get the service owner to grant you access, you can make a request serverside (e.g. from Node.js or PHP or Rails code) from a server that is under your control, then forward the data to your web page. However, depending on terms of service of the web service, you may be in breach, and you risk them banning your server.

Amadan
  • 169,219
  • 18
  • 195
  • 256
2

In fact, it depends on what your server REST API supports regarding JSONP or CORS. You also need to understand how CORS works because there are two different cases:

  • Simple requests. We are in this case if we use HTTP methods GET, HEAD and POST. In the case of POST method, only content types with following values are supported: text/plain, application/x-www-form-urlencoded, multipart/form-data.
  • Preflighted requests. When you aren't in the case of simple requests, a first request (with HTTP method OPTIONS) is done to check what can be done in the context of cross-domain requests.

That said, you need to add something into your AJAX requests to enable CORS support on the server side. I think about headers like Origin, Access-Control-Request-Headers and Access-Control-Request-Method.

Most of JS libraries / frameworks like Angular support such approach.

  • With jQuery (see http://api.jquery.com/jquery.ajax/). There are some possible configurations at this level through crossDomain and xhrFields > withCredentials.

  • With Angular (see How to enable CORS in AngularJs):

    angular
      .module('mapManagerApp', [ (...) ]
    
      .config(['$httpProvider', function($httpProvider) {
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
      });
    

If you want to use low-level JS API for AJAX, you need to consider several things:

  • use XMLHttpRequest in Firefox 3.5+, Safari 4+ & Chrome and XDomainRequest object in IE8+
  • use xhr.withCredentials to true, if you want to use credentials with AJAX and CORS.

Here are some links that could help you:

Hop it helps you, Thierry

Community
  • 1
  • 1
Thierry Templier
  • 182,931
  • 35
  • 372
  • 339
0

Here is how you get data.

var request = new XMLHttpRequest();
request.open('GET', 'https://www.codewars.com/api/v1/users/MrAutoIt', true);

request.onload = function() {
  if (this.status >= 200 && this.status < 400) {
    var resp = this.response; // Success! this is your data.
  } else {
    // We reached our target server, but it returned an error

  }
};

request.onerror = function() {
  // There was a connection error of some sort
};

request.send();

As far as running into same origin policy... You should be requesting from an origin you control, or you can try disabling Chrome's web security, or installing an extension such as Allow-Control-Allow-Origin * to force headers.

T_Conroy
  • 4,380
  • 9
  • 43
  • 92
  • If you tried that code, you would know that it has exactly the problem that OP is asking about. ("same-origin policy is giving me problems.") – Amadan Nov 11 '15 at 01:29
  • The question was 'How do you use a simple REST API’s with JavaScript'. But I've also added information about overcoming same-origin-policy issues. – T_Conroy Nov 11 '15 at 01:32
  • If he has problems with same-origin policy, he *obviously knows* how to make a request. And the anti-policy information you posted only works for debugging and learning purposes, and is completely and utterly unusable in normal web development, since you would need to ask every user of your web page to drop their security to accomodate your page. It would be like advertising a cleaning service as "Spotless kitchen, 100% satisfaction guaranteed, we require you to punch a hole in your outer wall to allow our workers access" instead of asking homeowners for a key. – Amadan Nov 11 '15 at 01:35
  • I know you're very concerned with your Reputation score, but you don't need to be so hostile and downvote a valid answer. I provided a valid solution to the question. If the question was about Cross Origin Requests that should have bene the title, not how to use rest API's. – T_Conroy Nov 11 '15 at 16:08
  • I have not referenced my answer even once in my response to you, and it is you who complains of downvotes. How am I the one concerned about my score? I have enough that I can eat up a revenge vote and not blink twice. And the purpose of the downvote is not to show hostility, but to mark answers that are not useful to the asker (and reading the question and getting its context helps with that). The title could be better; but the title is not the Question, title+body is. – Amadan Nov 12 '15 at 00:58
  • 1
    Thanks. Came for answer for question in subject (didn't even read Q's body) and got it. Worked for me (no same origin policy involved in my case) – Denis Sep 01 '19 at 22:33
-1

For a get method you could have something like this:

@section scripts{
<script type="text/javascript">
$(function()
{
        $.getJSON('/api/contact', function(contactsJsonPayload)
        {
            $(contactsJsonPayload).each(function(i, item)
            {
                $('#contacts').append('<li>' + item.Name + '</li>');
            });
        });
});
</script>
}

In this tutorial check the topic: Exercise 3: Consume the Web API from an HTML Client

1cgmr
  • 63
  • 1
  • 7