-1

I tried to use this Cat Facts API like so:

const URL = "https://catfact.ninja/fact?limit=1" // In browser, this displays the JSON

fetch(URL).then(response=> {
        console.log(response);
        return response.json();
    }
);

but I got

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://catfact.ninja/fact?limit=1. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

TypeError: NetworkError when attempting to fetch resource.

so after trying with

fetch(URL, {mode:'no-cors'})
    .then(response=> {
        console.log(response);
        return response.json();
    }
);

I now get

Response { type: "opaque", url: "", redirected: false, status: 0, ok: false, statusText: "", headers: Headers, body: null, bodyUsed: false }

SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data

I understand from here that I won't be able to use this API as intended. But if so, what is the purpose of it and how is it intended to be used (this info does not account for the issue)?

Zaff
  • 137
  • 3
  • 15

2 Answers2

3

An opaque response is one you cannot see the content of. They aren't useful in of themselves.

Setting mode: 'no-cors' is a declaration that you don't need to read the response (or do anything else that requires CORS permission).

For example, the JavaScript might be sending analytics data to be recorded by a server.

The benefit of no-cors mode is that it lets you send the data without getting exceptions reported in the JS console (which would (a) look bad if anyone opened it and (b) flood the console with junk that makes it hard to find real errors).


If you need to access the response, don't set mode: 'no-cors'. If it is a cross origin request then you will need to use some other technique to bypass the Same Origin Policy.


Aside: "Access-Control-Allow-Origin": "*" is a response header. Do not put it on a request. It will do nothing useful and might turn a simple request into a preflighted request.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Thanks. I didn't really understand `no-cors` before adding it (was trying anything). I will study that ASAP. So, in conclusion, this API can't be made use of? – Zaff Oct 21 '19 at 14:55
  • 1
    If the API doesn't grant permission with CORS (or JSONP) then you cannot make requests from client-side JS on other origins directly to it. – Quentin Oct 21 '19 at 14:57
-1

Adding {mode: 'no-cors'} is not a catch-all for CORS errors. You might be better off using a CORS Proxy.

This question might also be of use to you.

Alternatively, and depending on your needs, using a different API could be the easiest solution. I was able to return a cat fact from "https://meowfacts.herokuapp.com/". See below.

const URL = "https://meowfacts.herokuapp.com/"


async function getCatFact() {
  const response = await fetch(URL)
  console.log(await response.json())
}


getCatFact()
Matt Croak
  • 2,788
  • 2
  • 17
  • 35