Using fetch() to get data from API [duplicate] - javascript

This question already has answers here:
Handle response - SyntaxError: Unexpected end of input when using mode: 'no-cors'
(5 answers)
Closed 4 years ago.
When trying to resolve a fetch promise with JS is set the mode to 'no-cors' based on this answer. However setting the mode to 'cors' results in having:
Access to fetch at
'{endpoint}'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
So I wrote this in my function:
search() {
return fetch(`${baselink}${summonerEndpoint}${summoner}${apikey}`, {mode: 'no-cors'}).then(response => {
return response.json()
}).then(jsonResponse => {
console.log(jsonResponse);
if (!jsonResponse.info) {
return [];
}
return jsonResponse.info.items.map(info => ({
id: info.id,
accountId: info.accountId,
name: info.name,
profileIconId: info.profileIconId,
revisionDate: info.revisionDate,
summonerLevel: info.summonerLevel
}));
});
}
This results in following error Uncaught (in promise) SyntaxError: Unexpected end of input for return response.json(), but with no further message. What am I doing wrong?

If an opaque response serves your needs
It doesn't. You want to see the response. You can't see an opaque response (that is what opaque response means).
no-cors mode means that if the browser has to do anything that requires permission from CORS, it will fail silently instead of throwing an error.
So it is silently failing to get the response, then trying to parse that nothing as JSON (which throws a different error).
You need:
To not use no-cors mode
The server to grant permission using CORS
See this question for more information about CORS in general.

Related

using Riot games API with JS and fail to load response data

I have tried to use Riot games API, the below code has returned 'Status Code: 200'and seems like ok and then I got two errors as below.
Access to fetch at 'https://oc1.api.riotgames.com/lol/summoner/v4/summoners/by-name/edisona?api_key=RGAPI-xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
GET https://oc1.api.riotgames.com/lol/summoner/v4/summoners/by-name/edisona?api_key=RGAPI-xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx net::ERR_FAILED
So I added { mode: 'no-cors' } and error is gone, but there is no data that has been returned in the console after that I just use the URL directly and the browser shows the right data. I do not know why it happened, I appreciate if you can help me.
const name = 'edisona';
const api_key = 'RGAPI-xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
const url =
'https://oc1.api.riotgames.com/lol/summoner/v4/summoners/by-name/' +
name +
'?api_key=' +
api_key;
fetch(url)
.then(function(response) {
console.log(response);
}).catch(function(error) {
console.log('Request failed', error)
});
This seems like a Cross-Orgin request error (you didn't add CORS headers to the proxied request).
Try using CORS-Anywhere, a NodeJS reverse proxy to do just that.
Here's a demo. Try reading some about CORS: https://fetch.spec.whatwg.org/#cors-protocol-and-credentials

Posting form data to App Script not working [duplicate]

This question already has answers here:
Handle response - SyntaxError: Unexpected end of input when using mode: 'no-cors'
(5 answers)
Closed 4 years ago.
When trying to resolve a fetch promise with JS is set the mode to 'no-cors' based on this answer. However setting the mode to 'cors' results in having:
Access to fetch at
'{endpoint}'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
So I wrote this in my function:
search() {
return fetch(`${baselink}${summonerEndpoint}${summoner}${apikey}`, {mode: 'no-cors'}).then(response => {
return response.json()
}).then(jsonResponse => {
console.log(jsonResponse);
if (!jsonResponse.info) {
return [];
}
return jsonResponse.info.items.map(info => ({
id: info.id,
accountId: info.accountId,
name: info.name,
profileIconId: info.profileIconId,
revisionDate: info.revisionDate,
summonerLevel: info.summonerLevel
}));
});
}
This results in following error Uncaught (in promise) SyntaxError: Unexpected end of input for return response.json(), but with no further message. What am I doing wrong?
If an opaque response serves your needs
It doesn't. You want to see the response. You can't see an opaque response (that is what opaque response means).
no-cors mode means that if the browser has to do anything that requires permission from CORS, it will fail silently instead of throwing an error.
So it is silently failing to get the response, then trying to parse that nothing as JSON (which throws a different error).
You need:
To not use no-cors mode
The server to grant permission using CORS
See this question for more information about CORS in general.

How to use an API with opaque response?

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)?
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.
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()

Capturing full fetch errors [duplicate]

This question already has answers here:
Catching an Access-Control-Allow-Origin error in JavaScript
(2 answers)
Closed 3 years ago.
I have a fetch request:
fetch(url, {
}.then(function(resp))
// do something
}.catch(err => {
console.log(err);
}
My question involves grabbing the entire stack trace of err. For example, here is the real error message:
Access to fetch at 'https://www.google.com/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Great. This is a usable message. However, console.log(err) prints out TypeError: Failed to fetch. That's a really useless error message. Is there any way to capture that entire entire message that was logged in console (ie. var message = //the full error? err.stack does not seem to be a function and err.message returns the same useless Failed to fetch message
In general, when using fetch, you want to make use of the response.ok attribute, which is a bit confusing at first. This is a really good article on it, and it contains this example which is more or less what you want to do:
fetch("http://httpstat.us/500")
.then(function(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}).then(function(response) {
console.log("ok");
}).catch(function(error) {
console.log(error);
});
That said, you'll still get TypeError: Failed to fetch if you end up with a CORS error because they don't give you a nice error code (e.g. 404), they just cancel the HTTP request

Firebase Fetch - No Access-Control-Allow-Origin

I'm developing an app with React + Redux and I have my JSON database within a Firebase DB.
To do this I'm tryin to fetch my data from a valid URL (validated from Firebase simulator)
let firebase = 'https://******.firebaseio.com/**/*/***/*'
return (dispatch) => {
return fetch(firebase)
.then(res => res.json())
.then(json => dispatch({ type: 'GET_JSON', payload: json }))
}
This returns to me the error:
Fetch API cannot load https://console.firebase.google.com/project/****/database/data/**/*/***/*. Redirect from 'https://console.firebase.google.com/project//database/data/**///' to 'https://accounts.google.com/ServiceLogin?ltmpl=firebase&osid=1&passive=true…ole.firebase.google.com/project//database/data///**/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.`
I've tried many solutions, like adding to fetch's second argument { mode: 'no-cors', credentials: 'same-origin'}, but when I try this i get Uncaught (in promise) SyntaxError: Unexpected end of input.
What am I missing?
likely error that arise to cors blocked when using firebase is
when you initiate a put or get request with an incomplete firebase url
e.g
// wrong form
this.http.get('https://******.firebaseio.com/data') //this will throw an exception
// correct form
this.http.get('https://******.firebaseio.com/data.json')
I had this problem with a serviceworker implementation of fetch
self.addEventListener('fetch', (e) => {
fetch(e.request) // valid arg && works with firebase
fetch(e.request.url) // valid arg but will cause access-control error!
}
For a simple request to be allowed cross-domain, the server simply needs to add the Access-Control-Allow-Origin header to the response.
Also refer this turorial, if you have any doubts
Cross-Origin XMLHttpRequest
Using CORS.

Categories

Resources