I know this has been addressed a lot of times on SO, but all the answers are mostly in the vein of “add a certain header to the server”. In this case, the API (Shopify) works perfectly fine and can easily be accessed via curl.
I’ve tried this both with the Axios library and the Fetch API.
- I’ve tried every value for
referrer
,mode
, andreferrerPolicy
in the Fetch options. - I’ve confirmed my BasicAuth credentials are correct.
- I’ve tried in multiple browsers.
- I’ve tried from both localhost, localhost.com (set the value in my /etc/hosts), and from a server with a real domain name.
I can’t understand why this would work perfectly fine in cURL, but not with fetch().
Here’s a shortened version of my code:
const apiKey = 'mykey';
const apiPassword = 'mypass';
const apibase = 'https://my-shop-domain.myshopify.com/admin/';
const endpoint = 'locations.json';
var headers = new Headers({
"Authorization": "Basic " + btoa( apiKey + ':' + apiPassword ),
});
fetch( apibase + endpoint {
method: 'GET',
headers: headers,
mode: 'no-cors',
// cache: "no-store",
// referrer: "client",
// referrerPolicy: "origin",
// credentials: 'include'
}).then( resp => resp.json().then( resp => {
console.log( resp );
})).catch( err => {
console.error(err);
});
and the error that returns is
Access to fetch at ‘https://my-shop-domain.myshopify.com/admin/locations.json‘ from origin ‘https://localhost:8080‘ 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.
If Shopify doesn’t include the Access-Control-Allow-Origin header, why does the request work fine with cURL? There are node libraries and Ruby libraries to access the Shopify API, so it’s hard to believe that they simply don’t allow access from javascript at all.
So I guess my question is what can I do to access this API from with javascript?
2
Answers
You have to use FormData instead of JSON.
Why? explained:
The CORS policy is implemented in browsers to allow sharing resources between websites while preventing websites from attacking each other:
These policies only apply inside a browser. Presumably cURL works because it is making direct HTTP requests outside the context of a browser script. Which leads to how to work-around CORS restrictions…
Solutions:
3 Ways to Fix the CORS Error — and How the Access-Control-Allow-Origin Header Works explains how to bypass CORS restrictions. They all work by manipulating the request headers/origin:
Realistically, option #3 is the only real solution. SvelteKit endpoints make it super simple to proxy requests.