Fetch with headers doesn't work

Seem like whenever I add headers to the sandbox fetch in checkout ui extension, it causes cors issue. When I remove them it works as expected. May I know why this is happening?

eg. this doesnt work

    const postPurchaseOffer = await fetch(`${APP_URL}/api/offer`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${inputData.token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({data}),
    }).then((response) => response.json());

but this works

    const postPurchaseOffer = await fetch(`${APP_URL}/api/offer`, {
      method: "POST",
      body: JSON.stringify({data}),
    }).then((response) => response.json());

Is your server configured to allow *.shopify.com OPTIONS requests with the CORS headers?

Hi @Dylan
Do you know how to configured to allow *.shopify.com OPTIONS requests with the CORS headers?

Hi @zensein
Did you alredy fixed this issue, because I’m facing same error.

unfortunately not, still having the same issue

using remix-utils cors but it just doesn’t work if the request from the shopify checkout ui sandbox has headers.

What errors are you receiving? If you could provide more information about any errors messages etc

this is basically what I will get

Access to fetch at 'https://mid-complexity-going-heat.trycloudflare.com/api/checkout-offer' from origin 'https://cdn.shopify.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.

Yeah so you need to set the CORS headers in response to the OPTIONS request.
You can read more about CORS and understanding cross origin requests here, its really helpful Cross-Origin Resource Sharing (CORS) - HTTP | MDN

It’ll end up looking something like this, please do not copy and paste this without understanding it as it may cause you problems otherwise

{
    'Access-Control-Allow-Credentials': 'true',
    'Access-Control-Allow-Origin': origin,
    'Access-Control-Allow-Headers': 'authorization,origin,x-device-id',
    'Access-Control-Allow-Methods': 'GET,OPTIONS',
    'Access-Control-Expose-Headers': '',
    'Access-Control-Max-Age': '3600',
  }

this doesn’t work.

Theoretically if I did not set the CORS headers in response to the OPTIONS request, the fetch request without headers should not pass either.

It depends on your setup, if you are automatically responding to CORS requests with the framework. But not allowing credentials then only when you add credentials would it fail etc.

I would look into CORS and how your chosen framework handles it :blush:
If you inspect in the browser and watch the network requests (again depending on framework) this might give you some hints at what is going on.

I believe there isn’t any issue with the headers configuration on the server/framework. It seems like option requests via the cloudflare tunnel created by shopify cli for development is not being passed on to the server causing the issue.

I only run into this problem recently developing a POS UI extension app. The same fetch code used to work fine a while back. Did anyone come across a solution?

Thanks.

This isn’t an issue with fetch but with the CORS setup. :blush:

Please check your CORS setup is correct and follows the guidence in the POS docs Communicate with a server