javascriptexpresssafaricors

CORS violation occuring in safari, but not chrome


I have a react web app that makes calls to an express web server.

When I access the web app in chrome, everything works as expected.

When I access the web app in safari, I get an error:

XMLHttpRequest cannot load https://subdomain.example.com/path due to access control checks.

In the network tab, I see the failed call:

Summary
URL: https://api.example.com/path
Status: —
Source: —
Initiator: 
2.6ac8194f.chunk.js:2:223735

Request
Accept: application/json, text/plain, */*
Authorization: Bearer [...]
Origin: https://app.example.com
Referer: https://app.example.com/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15

Response
No response headers

Googling suggests this is a CORS error. My express api sets up cors using the npm package:

const express = require('express');
const cors = require('cors');

const app = express();

(async () => {
    app.use(cors());

    app.use('/path', [
       require('./apis/path'),
    ]);

}()


This article explained that safari has stricter CORS policies that chrome, and that you can't use wildcards and must include the schema. So I tried to specify allowed origins:

app.use(cors({ origin: ['https://app.example.com', 'https://other-app.example.com'] }));

The error stayed the same.

Is there something else I'm missing?


Solution

  • So, after much trial and error, it turned out that requests to ANY api failed when the page had first loaded, but later requests passed. This included OPTIONS requests, which made it appear like a cors earror. I resolved the issue by adding retry logic to the initial request.

    I used the p-retry with the default backoff pattern and up to 5 retries.

    I still don't understand why this happened, so if anyone could add an explanation it would be greatly appreciated.