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
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With