Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing API works fine with cURL but not with Fetch API [duplicate]

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, and referrerPolicy 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?

like image 954
JakeParis Avatar asked Sep 05 '25 07:09

JakeParis


1 Answers

Why? explained:

The CORS policy is implemented in browsers to allow sharing resources between websites while preventing websites from attacking each other:

  • SOP (same origin policy) prevents web sites from attacking each other but does not allow any sharing between origins.
  • CORS (cross origin resource sharing) relaxes SOP restrictions, but requires specific server headers/configuration.

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:

  1. Browser extension. (Not sure if this still works in 2022. Only works if user installs browser extension.)
  2. 3rd party request proxy. (The proxy linked in the demo is now limited due to abuse.)
  3. Build your own proxy.

Realistically, option #3 is the only real solution. SvelteKit endpoints make it super simple to proxy requests.

like image 94
Leftium Avatar answered Sep 07 '25 20:09

Leftium