Getting CORS Error when using fetch to get data - javascript

I am trying to access the API to get some data however i keep getting this CORS error. I have checked my code for any syntax errors but i can't find any. I have attached a picture of the error and my function which is supposed to get the data.
async function getData(){
const request = await fetch('https://api.igdb.com/v4/games', {
method: 'POST',
headers: {
'Client-ID': 'jglmao8u28qo1p9wltqne325i7xh3u',
'Authorization': 'Bearer 4xau27m6liukizor4z2l8mlb7vbpjk',
}
})
const response = await request.json();
console.log(response);
}

There is a great proxy out there used just for this - bypassing a CORS block. The source code is here: https://github.com/Rob--W/cors-anywhere, and you would use it like this:
https://cors-anywhere.herokuapp.com/https://api.igdb.com/v4/games
basically just adding the CORS-Anywhere URL before your actual image URL.
In your situation, it would be
async function getData(){
const request = await fetch('https://cors-anywhere.herokuapp.com/https://api.igdb.com/v4/games', {
method: 'POST',
headers: {
'Client-ID': 'jglmao8u28qo1p9wltqne325i7xh3u',
'Authorization': 'Bearer 4xau27m6liukizor4z2l8mlb7vbpjk',
}
})
const response = await request.json();
console.log(response);
}
If you get rate limited by that website, try https://circumvent-cors.herokuapp.com/, this is one that I have deployed from the GitHub source code, no modifications and I do not think it should rate limit you.
Cheers, and let me know if this works.

Related

How can I update the message body using gmail API in javascript

I have got the message body. Now I want to update it according to my needs. I am using this login/code. but it says 400 error. I think issue is in body parameter of the request. Would you please help me there?
var token = localStorage.getItem("accessToken");
var messageId = "18514426e2b99017";
async function updateMessageBody() {
var updatedBody = "Hello,\n\nThis is the UPDATED message body.\n\nBest regards,\nJohn";
const API_KEY = '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-CXIk';
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
const response = await fetch(`https://gmail.googleapis.com/gmail/v1/users/me/messages/18514426e2b99017/modify?key=['API_KEY']`, {
method: 'POST',
headers: headers,
body: JSON.stringify({
raw: window.btoa(unescape(encodeURIComponent(updatedBody)))
})
});
if (!response.ok) {
// throw new Error(`Request failed with status code ${response.status}`);
}
return await response.json();
}
updateMessageBody()
.then(response => {
console.log('Message body updated successfully:', response);
})
.catch(error => {
});
Checking the documentation, it states that a message body can't be altered once it has been created, meaning that once you have already created an email this message can't be changed. You can verify this here.
You can instead update a message draft which is possibly what you are trying to do, however using the endpoint you have in your code this won't be possible and will lead to the error message you are getting, try using instead the users.draft.update method that allows you to modify the content of the draft sitting in your mailbox. Please note as well that using the method users.messages does not have any update method as they only have the modify one's, those methods can only update the labels though so please be aware of that.

Axios response.data object returns garbage on simple API GET request

I wrote a quick test function to try out Axios, and the response.data object that gets returns is garbled. I'm not sure what I'm doing wrong— I've tried Googling around for this to no avail, and all of the Axios tutorials I've found seem to be doing exactly what I'm doing.
Here's the GET request I make:
var axios = require('axios');
const getCatFact = async () => {
const url = "https://catfact.ninja/fact";
const response = await axios.request({
method: 'GET',
url: url,
});
console.log(response.data);
};
getCatFact();
And here's what the responses look like:
%O�j�#
��aO-����������{�nٕ������a4��0J��>���+�,D�ˢ
�bV�G��/I�Cw�Rf¤L���Z�5w����]ӄ���s������
I.b�z"�IR��M����(N3��Y���귴���m�ۤ� ��Xuz���t�uS�y\��5=61������4y
�����!{��
I've tried:
Loading the URL in Chrome and making the GET request via Postman to validate that the API itself is not the problem.
Testing with a different API (https://jsonplaceholder.typicode.com/posts/1), which has the same issue.
I'm expecting the snippet above to return a response that looks something like this:
{"fact":"Julius Ceasar, Henri II, Charles XI, and Napoleon were all afraid of cats.","length":74}
In v1.2.1, it is fixed this error.
You need to add Accept-Encoding with 'application/json' in axios get header.
var axios = require('axios');
const getCatFact = async () => {
const url = "https://catfact.ninja/fact";
const response = await axios.request({
method: 'GET',
url: url,
headers: {
'Accept-Encoding': 'application/json'
}
});
console.log(response.data);
};
getCatFact();
Will be get this result
$ node get-cat.js
{
fact: 'Cats have about 130,000 hairs per square inch (20,155 hairs per square
centimeter).',
length: 83
}

Fetch API call not fetching cookies in expo react native?

I'm trying to send a post request to the server but the response does not contain 'set-cookie' header but the cookie is visible in postman.
This is the code:
axios.defaults.withCredentials = true;
let config = {
method: 'post',
url: 'https://app.bhive.fund/v1/api/account/signin',
headers: {
'Content-Type': 'application/json',
},
data: form
}
const res = await axios(config)
console.log(res.status)
console.log('set-cookie: ');
console.log(res.headers['set-cookie']);
console.log(res.headers);
return res;
This is the screenshot of the log
This is the screenshot of postman
That's because of the res.headers can't be accessed like an object.
You have to use the get()-method specified in order to get the cookie.
Try this instead of accessing the value right away by specifying the index with the brackets:
console.log(res.headers.get("Set-Cookie"));

How to get content-type from the response headers with Fetch

I'm trying to access the returned content-type from my GET request so I can decide the kind of preview I want to like for html maybe pass through an iframe and for a PDF maybe some viewer. The problem is when I do console.log(response.headers) the object returned doesn't have content-type in it but when I check the networks tab the response headers has content-type:html/text. How can I get the content-type from the response headers?
this is how my GET request looks like
const getFile = async () => {
var requestOptions = {
method: "GET",
headers: context.client_header,
redirect: "follow",
};
let statusID = context.currentStatus.ApplicationID;
var response = await fetch(
process.env.REACT_APP_API_ENDPOINT +
"/services/getStatus?ApplicationID=" +
statusID,
requestOptions
);
console.log(response.headers);
if (response.ok) {
let fileHtml = await response.text();
setfileURL(fileHtml);
} else {
alert.show("Someting went wrong");
}
};
The Headers object isn't a great candidate for console.log() since it is not easily serialisable.
If you want to see everything in it, try breaking it down to its entries via spread syntax
console.log(...response.headers)
You'll probably find that you can in fact access what you want via
response.headers.get("content-type")
See Headers.get()

cross origin for amazon lambda function from localhost in gatsby site

I have the following code which works when I run it as a local serverless function with netlify dev, but I need it to run cross origin from a dev server to the hosted server function. I put the function in a aws lambda function but I am getting a cross origin blocked error on my https:dev.website.com, I thought I have the correct headers in the return object so not sure why I am getting a cross origin error.
Any help would be great
const sanityClient = require("#sanity/client");
const client = sanityClient({
projectId: "random-id",
dataset: "production",
useCdn: true,
});
exports.lambdaHandler = async (event, context) => {
var body = JSON.parse(event.body);
//console.log(body.price_id)
try {
const checkPriceId = async (test) => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`;
const documents = await client.fetch(query, {}); // this could throw
return documents.map((document) => document.sold);
};
var ok = checkPriceId().then((test) => {
return new Promise(function (resolve, reject) {
//console.log(test) // this will log the return value from line 7
console.log(test);
resolve(test);
});
});
var bools = await ok;
// prettier-ignore
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods':'GET, POST, OPTION',
},
body: JSON.stringify({
sold: bools,
}),
};
} catch (err) {
return { statusCode: 500, body: err.toString() };
}
};
This is my request to the function if that helps
var fetchUrl = https://random.executue-api.aws.com/prod/sold //not exact
var fetchData = async function () {
const response = await fetch(fetchUrl, {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
price_id: final,
}),
})
.then(res => {
return res.json()
})
.catch(error => console.log(error))
return response
}
Update:
I tried adding cors the way suggested in the answer below, but it failed seen below so I tried manually adding the method response seen after.
I still get a cross domain error. And I have changed the domain so it is now https as well. Really stuck here.
I was looking into this more, and it seems like before it does the actual post it does a cors check at the options method, so I added in the same access control headers, and deployed but did not work. Don't quite get this.
Your headers look ok to me. (note: If you mix HTTP and HTTPS you are most likely to get a mixed content error in the client). If it is ONLY a CORS issue that you are seeing in the console in the web browser, then you might not have configured the API Gateway correctly in AWS.
In AWS, go to API Gateway and you should see something like the below:
Make sure that you enable CORS and then redeploy.
UPDATE:
Just looking at a previous implementation of a lambda function I setup with AWS. The headers I declared were as follows:
headers: {
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Allow" : "GET, OPTIONS, POST",
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
"Access-Control-Allow-Headers" : "*",
"Access-Control-Allow-Credentials" : true
}
Your headers look OK to me though. However, when you created the method in the API Gateway, did you select Use Proxy Lambda Integration? (see screenshot).
Your client side fetch request looks ok. For reference mine was:
const url = 'your url';
const options = {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
};
fetch(url, options).then(res => res.json());
Unrelated to this issue, but its not advisable to mix Async/Await with .then promise chaining. But this isn't the issue you are having. Just something to note.
Check the values from your Integration Response / try setting them manually for both OPTIONS and POST (and if that works, make sure you are passing through the response correctly from the lambda).
Your POST action should only require the Access-Control-Allow-Origin header. The other two (Access-Control-Allow-Methods, Access-Control-Allow-Headers) belong in the OPTION action. See this writeup, and note the full example exchange for a preflighted request (in grey): https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests

Categories

Resources