Fetch request is being being blocked by CORS policy? - javascript

I'm making an API request to the Beehiiv API, to get my list of publications.
Inside my React component, I've set up a fetch request to the API. However the request is being being blocked by the CORS policy. Request code below:
async function makeRequest(){
const fetchOptions = {
method: 'get',
headers: {
"X-ApiKey": '<MY API KEY>',
"Content-Type": "application/json",
"Access-Control-Allow-Origin" : '*'
},
}
fetch('https://api.beehiiv.com/v1/publications', fetchOptions).then( response => response.json() )
.then( data => console.log(data) )
}
makeRequest();
The response in the console is as follows:
Access to fetch at 'https://api.beehiiv.com/v1/publications' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
Calling other API's does not seem to result in getting blocked.
Any ideas on why this may be happening? Please let me know! Thanks!

From beehiiv API documentation:
API keys are considered sensitive data and should not be shared with anyone. Be careful not to expose the API key in your source code or any other public location (including front-end code).
The API isn't supposed to be called from the frontend.
You need to make AJAX requests to your own server, which then calls the API, so the API key isn't exposed.

Related

Access to fetch at <my-google-cloud-function> from origin 'https://www.reddit.com' has been blocked ... CORS

I am working on a Google Chrome extension to block a subset of images from posts in a user's Reddit feed based on some backend computer vision run in Python in Google Cloud Storage. The Python code takes a single argument (the URL of an image in Reddit), which is passed in JavaScript via:
const api_url = https://<my-google-chrome-url>
var curUrl = $(this).attr("src")
fetch(api_url,{
method: 'POST',
body: JSON.stringify(curUrl),
headers: {
'Content-Type': 'application/json'
},
})
.then(data => {console.log(data)})
When the extension's code runs, I get the following in the console:
Access to fetch at 'https://this-is-the-path-to-my-google-cloud-function' from origin 'https://www.reddit.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
I have tried multiple solutions, enumerated below:
I have followed the instructions here, such that by using Google's gsutil, I am able to confirm the following to be true for the bucket that my function lives in: [{"maxAgeSeconds": 3600, "method": ["GET", "POST"], "origin": ["https://www.reddit.com"], "responseHeader": ["Content-Type"]}]. I have also tried having ["*"] as my origin, to no avail.
I have also tried using in my fetch, mode: no-cors with no success.
Any suggestions or solutions would be greatly appreciated!
For what you mention, the CORS error in this case seems to come from the Cloud Function.
In order to address this, you should configure CORS for the Cloud Function, not Cloud Storage.
CORS consists of the preflight request and the main request. In your function you should check for preflight request by checking if the request's method is OPTION and if so, respond the appropriate headers. Here is a sample:
def cors_enabled_function(request):
# For more information about CORS and CORS preflight requests, see
# https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
# for more information.
# Set CORS headers for the preflight request
if request.method == 'OPTIONS':
# Allows GET requests from any origin with the Content-Type
# header and caches preflight response for an 3600s
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '3600'
}
return ('', 204, headers)
# Set CORS headers for the main request
headers = {
'Access-Control-Allow-Origin': '*'
}
return ('Hello World!', 200, headers)
For more information, you can read the docs

API Gateway failing to enable CORS

When I attempt to request a lambda-backed API (using API gateway, deployed using the CLI and Cloud Development Kit) from my react app, I get the following error:
Access to XMLHttpRequest at 'https://xxxxxxxxxx.execute-api.eu-west-1.amazonaws.com/prod/xxxxx' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET https://xxxxxxxxxx.execute-api.eu-west-1.amazonaws.com/prod/xxxxx net::ERR_FAILED
My API resources defined using the CDK are all passed into this method
Like explain here, you need to enable CORS in API Gateway, BUT you also need to return an Access-Control-Allow-Origin header from your Lambda because API Gateway doesn't add that automatically to the responses.
Here is a sample of what my Lambda return for a simple Get :
return {
headers,
body: JSON.stringify(response.Item),
statusCode: 200
};
const headers = {
"Access-Control-Allow-Origin": "*", // Required for CORS support to work
"Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS
}

CORSS with proxy url

I am making a react application where I use an API. However, I couldn't make the API work and I opted for CROSS, using a proxy URL (https://yacdn.org/proxy/). Now I can retrieve my desired information from the API but after some time my application crashes.
I get an error saying:
Access to fetch at 'https://yacdn.org/proxy/https://apps.des.qld.gov.au/species/?op=getspecies&kingdom=animals&family=Macropodidae' 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.
I tried using mode: 'no-cors'. I am not allowed to use Chrome-extension and was told to come up with a backend solution that just forwards (proxies) the call to the API and returns the result
How can I solve this? Any hint will be appreciated.
You can use fetch to achieve this:
fetch('https://cors.io/?https://apps.des.qld.gov.au/species/?op=getspecies&kingdom=animals&family=Macropodidae',
{
method: 'GET'
})
.then(res => {
res.text().then((s) => console.log(JSON.parse(s)))
})
.catch(error => {
// Handle your error
throw new Error('Failed while checking data from au services:' + error)
})
Use this proxy server:
https://cors.io/?...
And also for the response is important to convert into JSON object:
res.text().then((s) => console.log(JSON.parse(s)))
Hope it help you.

Google Maps Place request from browser

Trying to get a request from a React app to Google Maps API working but getting CORS issues. Google says it supports CORS but not sure how to make the right request to be able to retrieve place data.
const src = `https://maps.googleapis.com/maps/api/place/details/json?key=${GOOGLE_API_KEY}&placed=${id}&fields=formatted_phone_number`
const headers = {
'Access-Control-Allow-Origin' : '*'
}
fetch(src, { mode: 'cors', headers: headers }).then(response => console.log(response))
The src itself is fine but getting this issue:
Failed to load
https://maps.googleapis.com/maps/api/place/details/json?key=(keyRemoved)&placed=(placeRemoved)&fields=formatted_phone_number:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8000' is therefore not allowed
access.
I think your best bet is to use the Places service in the Javascript API
https://developers.google.com/maps/documentation/javascript/reference/3.exp/places-service#PlacesService

How can do you make an API call without a proxy server?

I have a URL for a Google Places API that returns the proper json, but when I use fetch, I get this error:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' 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.
Here's my code
fetch(url, {
mode: 'cors',
headers: {
'Access-Control-Allow-Origin': '*'
}
})
.then(res => res.json())
.then(data => console.log('data', data))
.catch(e => console.log('e', e))
The reason why I don't want to make a proxy server is that I'm using a static site hosting service (and it's just more work to make a proxy server). I figured that if I already have a working url, it should be pretty simple to just fetch the json from that url. This is for a React app (made with create-react-app).

Categories