2

I'm attempting to pull JSON data from openlibrary using AngularJS's $http. I'm using the ISBN 1560761164

Here is the code.

 $scope.fetch = function(isbn) {
       $scope.method = 'JSONP';
       $scope.url = "http://openlibrary.org/search.json?isbn=";

    $http({method: $scope.method, url: $scope.url + isbn + "&callback=JSON_CALLBACK"}).
    success(function(data, status) {
      $scope.status = status;
      $scope.data = data;

     }).
     error(function(data, status) {
        $scope.data = data;
        $scope.status = status;
     });

};

I end up getting the following error in search.json

Uncaught SyntaxError: Unexpected token :

I'm really not sure why it's dying in this context, I tried removing the P from JSONP (hoping that it would reply correctly) but I got a 404 response, and it didn't seem to work (happy to be corrected on that one).

This is the contents of search.json (in the developer console):

  {
   "start": 0, 
   "num_found": 2, 
   "numFound": 2, 
   "docs": [
    {
     "title_suggest": "Dark heart", 
     "edition_key": [
      "OL24911358M"
     ], 
     "isbn": [
      "1560761164", 
      "9781560761167"
     ], 
     "has_fulltext": false, 
     "text": [
      "OL24911358M", 
      "1560761164", 
      "9781560761167", 
      "Tina Daniell", 
      "Copyright Paperback Collection (Library of Congress)", 
      "25151948", 
      "OL776411A", 
      "American Fantasy fiction", 
      "Dark heart", 
      "OL16007376W", 
      "Tina Daniell", 
      "TSR Inc.", 
      "90071496"
     ], 
     "author_name": [
      "Tina Daniell"
     ], 
     "oclc": [
      "25151948"
     ], 
     "contributor": [
      "Copyright Paperback Collection (Library of Congress)"
     ], 
     "author_key": [
      "OL776411A"
     ], 
     "subject": [
      "American Fantasy fiction"
     ], 
     "title": "Dark heart", 
     "publish_date": [
      "1992"
     ], 
     "ebook_count_i": 0, 
     "publish_place": [
      "Lake Geneva, WI"
     ], 
     "edition_count": 1, 
     "key": "OL16007376W", 
     "publisher": [
      "TSR Inc."
     ], 
     "language": [
      "eng"
     ], 
     "lccn": [
      "90071496"
     ], 
     "last_modified_i": 1312010687, 
     "publish_year": [
      1992
     ], 
     "first_publish_year": 1992
    }, 
    {
     "title_suggest": "Dark Heart (Dragonlance: The Meetings Sextet, Vol. 3)", 
     "edition_key": [
      "OL8617758M"
     ], 
     "cover_i": 790919, 
     "isbn": [
      "1560761164", 
      "9781560761167"
     ], 
     "has_fulltext": true, 
     "text": [
      "OL8617758M", 
      "1560761164", 
      "9781560761167", 
      "Tina Daniell", 
      "darkheart00dani", 
      "OL776411A", 
      "Accessible book", 
      "American Fantasy fiction", 
      "In library", 
      "Protected DAISY", 
      "Dark Heart (Dragonlance: The Meetings Sextet, Vol. 3)", 
      "OL4132436W", 
      "Wizards of the Coast", 
      "KitiaRa Uth MataR stood iN thE shadE of a loNE oak on a small rise that overlooked a shallow valley."
     ], 
     "author_name": [
      "Tina Daniell"
     ], 
     "ia": [
      "darkheart00dani"
     ], 
     "author_key": [
      "OL776411A"
     ], 
     "subject": [
      "Accessible book", 
      "American Fantasy fiction", 
      "In library", 
      "Protected DAISY"
     ], 
     "title": "Dark Heart (Dragonlance: The Meetings Sextet, Vol. 3)", 
     "ia_collection_s": "printdisabled;inlibrary;browserlending;americana;internetarchivebooks", 
     "printdisabled_s": "OL8617758M", 
     "ebook_count_i": 1, 
     "ia_box_id": [
      "IA127609"
     ], 
     "edition_count": 1, 
     "first_publish_year": 1992, 
     "key": "OL4132436W", 
     "id_goodreads": [
      "92908"
     ], 
     "public_scan_b": false, 
     "publisher": [
      "Wizards of the Coast"
     ], 
     "language": [
      "eng"
     ], 
     "last_modified_i": 1340764985, 
     "lending_edition_s": "OL8617758M", 
     "id_librarything": [
      "193011"
     ], 
     "cover_edition_key": "OL8617758M", 
     "first_sentence": [
      "KitiaRa Uth MataR stood iN thE shadE of a loNE oak on a small rise that overlooked a shallow valley."
     ], 
     "publish_year": [
      1992
     ], 
     "publish_date": [
      "January 1, 1992"
     ]
    }
   ]
  }

Does anyone have any suggestions for pulling this data from a clientside application without having to deal with a backend?

EDIT: Here is the link to the api of the call. https://openlibrary.org/dev/docs/api/search

The URL format for API is simple. Take the search URL and replace /search with /search.json.

http://openlibrary.org/search?q=the+lord+of+the+rings

http://openlibrary.org/search?title=the+lord+of+the+rings

http://openlibrary.org/search.json?author=tolkien

http://openlibrary.org/search?q=the+lord+of+the+rings&page=2

I guess it doesn't explicitly state isbn, but the data returns correctly if you visit the URL it'll actually show a valid JSON object I just can't seem to "retrieve" it for some reason.

Example Working URL that fails:

http://openlibrary.org/search.json?isbn=1560761164&callback=angular.callbacks._0

Additional Info:

Calling it without the JSONP and just using JSON as the Method I get the following Console Errors:

OPTIONS http://openlibrary.org/search.json?isbn=1560761164 405 (Method Not Allowed) angular.js:7962

XMLHttpRequest cannot load http://openlibrary.org/search.json?isbn=1560761164. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

This is the JSON request headers:

OPTIONS /search.json?isbn=1560761164 HTTP/1.1
Host: openlibrary.org
Connection: keep-alive
Cache-Control: no-cache
Access-Control-Request-Method: JSON
Pragma: no-cache
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Access-Control-Request-Headers: accept
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

and response:

HTTP/1.1 405 Method Not Allowed
Server: nginx/0.8.54
Date: Wed, 11 Jun 2014 23:31:10 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Allow: GET, HEAD, POST, PUT, DELETE
X-OL-Stats: ""
Connection: Keep-Alive

Here are the JSONP request headers:

GET /search.json?isbn=1560761164&callback=angular.callbacks._0 HTTP/1.1
Host: openlibrary.org
Connection: keep-alive
Cache-Control: no-cache
Accept: */*
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: session="/people/onaclov2000%2C2014-06-02T20%3A09%3A47%2C350bc%2428943338f8cbec882f19b2851f81ae1e"

and response:

HT

TP/1.1 200 OK
Server: nginx/0.8.54
Date: Wed, 11 Jun 2014 23:32:27 GMT
Transfer-Encoding: chunked
X-OL-Stats: "IB 1 0.008 MC 1 0.001 SR 1 0.075 TT 0 0.091"
Connection: Keep-Alive
onaclov2000
  • 5,741
  • 9
  • 40
  • 54
  • Apparently, this is not a JSONP response. Does the api claim to support this format at all? – Bergi Jun 11 '14 at 23:18
  • It appears they do unless I'm misreading. (although I'm still fairly new at understanding these responses/requests) – onaclov2000 Jun 11 '14 at 23:29
  • I tried adding "headers : {accept : "application/json"}" to my $http request at one point, but it has made no difference and in fact when I look at the request (in the developer console) it still shows accept : */* which I don't know if that's right or not – onaclov2000 Jun 11 '14 at 23:30
  • No, they do only support JSON. No mentioning of JSONP. – Bergi Jun 11 '14 at 23:32
  • Ok, so can you point me in the direction of handling the request using JSON and not JSONP? I'm not really sure what needs to happen differently. – onaclov2000 Jun 11 '14 at 23:33
  • 1
    Well, it seems to neither support JSONP nor CORS, so you need to find another [way to circumvent the SOP](http://stackoverflow.com/q/3076414/1048572). – Bergi Jun 12 '14 at 00:59

1 Answers1

0

Solution: Get ahold of the developers of the website and request CORS to be available (or JSONP).

Took me a bit, but I did discover that I couldn't call JSON, I had to use GET

I looked at the response header and saw this which lead me to the GET side of things instead of JSON: Notice it says Allow Method Get,Options <-- This is what indicated GET was allowed not JSON.

HTTP/1.1 200 OK
Server: nginx/0.8.54
Date: Fri, 13 Jun 2014 13:08:19 GMT
Transfer-Encoding: chunked
Access-Control-Allow-Origin: *
Access-Control-Allow-Method: GET, OPTIONS
Access-Control-Max-Age: 86400
Connection: Keep-Alive

Once I did that, here is what I used (I literally looked all over and just pulled stuff together till I figured it out).

 <script>
      var app = angular.module("myapp", []);

app.config(function($httpProvider) {
    //Enable cross domain calls
    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
});
      function MyController($scope, $http) {
       $scope.fetch = function(isbn) {
           $scope.method = 'GET';

           $scope.url = "http://openlibrary.org/search.json?isbn=";

        $http({method: $scope.method, url: $scope.url + isbn  
                }).
        success(function(data, status) {
          $scope.status = status;
          $scope.data = data;

         }).
         error(function(data, status) {
            $scope.data = data;
            $scope.status = status;
         });
};
      }
    </script>
onaclov2000
  • 5,741
  • 9
  • 40
  • 54