CORS Errors solved with a Cloudflare Service Worker
2021-10-20
I built a site recently practice API calls. It makes a call to the Vic Data COVID testing feed and filters the results based on user input.
I initially set up the data as a public GIST which I queried using a fetch(). I'd pull a fresh run of the data in the morning and update the GIST for the day. This worked well with a couple of things to note
- the live data feed actually gets updated in realtime with information such as current wait time, so as soon as I've updated my GIST the data is already out of date
- it's tedious to manually update the data feed every day, and sometimes I can't be bothered, eg Sunday morning :)
The reason I set up the data in a public GIST was that when I first tried to make a fetch to the data feed, I encountered every web developers favourite issue - CORS errors
Access to fetch at ‘https://discover.data.vic.gov.au/dataset/victorian-testing-site-locations-for-covid-19’ from origin ‘http://localhost:8080’ 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.
Actually an opaque response does not serve my needs, but never fear, there is a solution!
In short, my error is this, no CORS header is getting sent back to my browser from discover.data.vic.gov.au so my browser decides the returned content is a security risk and refuses to play ball. The solution to this is to use a proxy, a gobetween that will add a CORS header into the response for me and make my browser happy.
You can read more about CORS and the proxy solution here
There are a bunch of hosted CORS proxy servers around that you can use in a development environmnet, but most of them are not supported anymore. I found that thingproxy worked and helped me understand the basics of what to do. Essentially we prefix our fetch() url with the proxy url, in this case "https://thingproxy.freeboard.io/fetch/"
const url ="https://thingproxy.freeboard.io/fetch/https://pausedatahealth01.blob.core.windows.net/testsitemaster/testingsitedata/TestSitesData.json";
fetch(url)
.then(response => {
console.log(response);
if (!response.ok) {
throw new Error("Network response was not ok")
}
return response.json()
});
.then(resultData => {
console.log("ok", resultData);
});
.catch(error => {
console.error(
"There has been a problem with your fetch operation:",
error
)
});
This is fine for development, and maybe this is all you need to help you overcome CORS errors using localhost, but I needed a more permanent solution. Enter Cloudflare service workers. The Cloudflare documentation and tutorials section is extremely well set up. More info here
I setup a service worker in my dashboard and using the quickedit feature copied in some of the freely available Cloudflare starter code.
A little editing was required on my end
I updated the API url
const API_URL = "https://pausedatahealth01.blob.core.windows.net/testsitemaster/testingsitedata/TestSitesData.json"
and I updated the endpoint to my handle
const PROXY_ENDPOINT = "/tolka/"
Finally I updated the URL in my app to include the url of my service worker with the endpoint appended, followed by the url of the API.
const url ="https://<mydevworkerurl>.workers.dev/tolka/https://pausedatahealth01.blob.core.windows.net/testsitemaster/testingsitedata/TestSitesData.json"
Success!
You can use my site here https://gettestedvictoria.com/