Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

goodreads API gives Cross-Origin Request Blocked: error in javascript

i am trying to list books from goodreads in javascript but it gives Cross-Origin Request Blocked error.

const uri = ‘https://www.goodreads.com/search/index.xml?key={mykey}=Ender%27s+Game';

let f = new Headers();

let req = new Request(uri, {

method : ‘GET’,

headers :f,

mode :’cors’

});

fetch(req).then((response) => {

}).then( (jsonData) => {

}) .catch( (err) => {

console.log(‘err’);

});

});

how to solve it and retrieve result.

I gone through many links here but nothing seems helps me. Can anyone helps me to figure out the issue .

regards

like image 927
Karamzov Avatar asked Dec 20 '25 21:12

Karamzov


1 Answers

For those, like me, who have lost all hope to find an answer to this problem and have arrived here with all faith, but there is no answer in SO, here is the approach to follow.

Background. Solving this issue has been asked since 2015 (according to Goodreads forum). At least 6 years, and considering how easy to solve is, throw away your hopes, because it ain't gonna happen, sadly.

Side note. Do not bother to ask Goodreads for JSON response. Goodreads will give you nothing, but an HTML iframe. Which, by the way, it is not a JSON response, as you could guess. Instead, use XML response (format=xml). No fear, there is a library in Node to help you out: xml2js

Solution. As in many CORS problems, this is solved with a reverse proxy (given that you cannot change the server).

There are many alternatives. I found cors-anywhere, with a public server to point (https://cors-anywhere.herokuapp.com/), but it can be also installed on your machine. For Goodreads, the request URL should be in this format: https://cors-anywhere.herokuapp.com/https://www.goodreads.com/book/isbn/{isbn}?format=xml&user_id={userid}&key={apikey}.

I end up using axios library to make the connections (as recommended in this Goodreads developers post)

My solution for Angular (but I guess it could be easily transformed to any JS system, including plain web).

. . .
import axios from 'axios';
import { AxiosInstance } from "axios";
import * as xml2js from 'xml2js'; // To parse XML to JSON-like
. . .


export class YourService {

  private axiosClient: AxiosInstance;

  constructor(private httpClient: HttpClient) {

    this.axiosClient = axios.create({
            timeout: 3000,
            headers: {
                "X-Initialized-At": Date.now().toString()
            }
        });

  }


  async getBook(isbn: string):Promise<YourBookObject> {
    . . .
    var config = {headers: {"X-Requested-With" : "XMLHttpRequest"}};
    var url = "https://cors-anywhere.herokuapp.com/https://www.goodreads.com/book/isbn/"+isbn+"?format=xml&user_id="+userid+"&key="+apikey
    await this.axiosClient.get(url, config )
    .then(function (response) {
          if(response.status == 200){
            xml2js.parseString( response.data, function (err, result) {
              console.log("XML-JSON Parse")
              console.log(result); // Prints JSON object!
              . . .
            });
          }
        })
    .catch(function (error) {
          console.log(error);
    })
    . . . // additional checks to response and return
  }

}

Hope I help, although 1 year late :)

like image 117
Sergio Avatar answered Dec 23 '25 10:12

Sergio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!