CORS works on Chrome but not on Safari or on iOS device


I make this story longer than strictly necessary in the hope that others will find my explorations useful.

I want to use HttpClient (from @angular/common/http) to load a static JSON file from a hosted web site. I want the same code to run in both browsers and on devices and therefore want to avoid using the native HTTP plugin.

My first loading attempt failed with CORS (Cross-Origin Resource Sharing) errors. I ran ionic serve on both Chrome and Safari as well as the installed app on my iOS device to no avail.

I therefore configured the server (Apache) to allow CORS by adding an .htaccess file with the following contents to the appropriate directory:

Header set Access-Control-Allow-Origin "*"

This made ionic serve work for Chrome but not for Safari. Loading on the device did not work either.

I then disabled cross-origin restrictions in Safari by selecting the menu item:

Develop | Disable Cross-Origin Restrictions

This made ionic serve work on Safari.

Since Ionic’s default VKWebView container is CORS-compliant I swapped it for the older non-compliant container UIWebView by adding the following line to config.xml:

<preference name="CordovaWebViewEngine" value="CDVUIWebViewEngine" />

This made loading on the device work, which means I sort of accomplished my goal. However, I am not really happy with this solution since I want to understand what is going on. I would prefer to use the VKWebView container since it is the new default container with supposedly better performance than the old one. But no matter what CORS setting I add to the .htaccess file on Apache, I can’t make neither the app nor Safari to work ‘out-of-the-box’.

My question is therefore:

  • Has anyone managed to configure a server with explicit CORS settings for use from Safari and installed apps, using the regular HttpClient component and the WKWebView container? If yes, with which settings? I assume that the root cause is how WebKit handles CORS since WebKit is supposedly used by both Safari and the WKWebView container.

I have tried the native HTTP plugin and it works on the device but obviously not in the browser. I have also tried the plugin (which hides native HTTP calls behind the HttpClient interface) but I never got it to run past app initialization.

1 Like

I had a similar problem when sending GET requests to an AWS API Gateway endpoint. I could see the OPTIONS preflight response contained the required CORS headers including Access-Control-Allow-Origin “*”, however Safari was still complaining that Access-Control-Allow-Origin was not present and failing the GET request.

The problem in my case was that Access-Control-Allow-Origin was not being returned as a header in the GET response. As soon as I updated the endpoint to return the header, the call worked on both Safari and on the iOS device.

Hi - I’m using this plugin and it works fine for me. Maybe you should investigate what’s happening on app initialisation?

Thanks for the info. I believe the header is returned correctly since it didn’t work at first but then when I added the same header as you, Chrome started working so obviously it made some kind of difference. I vaguely remembering somewhere that Safari uses some non-standard CORS settings so maybe this could have something to do with that I haven’t got it working.

I guess I should. There is a lot going on in my app at startup and I should probably strip it down to a minimum to see exactly what fails. My problem is that I am quite new to Ionic, Typescript and VS Code so I haven’t learned the ropes yet. If you have any good tips on how to see what goes on at startup I would appreciate those.

found the solution? im having the same issue, im using the same plugin and its not working on android. i would rather use the common httpclient