This is a guest post by Rodrigo Fernández @FdezRomero, Full-stack Javascript Developer, Ionic contributor, and co-organizer of the Ionic Madrid meetup group.

One of the most distinctive features of Ionic is its long-term use and support of web standards, even more so now with Ionic 4, which uses Web Components under the hood. This commitment to universal web standards helps web developers decrease the learning curve of building mobile and desktop apps with the same technologies we know and love: HTML, CSS (or SCSS) and Javascript (or TypeScript!).

We can easily deploy these apps as Progressive Web Apps (PWAs) to be used directly from the browser, publish them to the app stores by wrapping them in a native shell like Cordova or Capacitor, or do both. But, the common denominator in each of these situations is that Ionic apps always run in a browser or webview.

This is great, because no matter the platform, we can use the same web APIs to run our app in iOS, Android, desktop (macOS/Windows/Linux with Electron), and even inside browser extensions! It also means that our apps are protected from common attack vectors, like Cross-Site Request Forgery (CSRF).

One of these protection mechanisms is Cross-Origin Resource Sharing (CORS), used by browsers and webviews to restrict HTTP and HTTPS requests made from scripts to resources in a different origin for security reasons—mainly to protect your user’s data and prevent attacks that would compromise your app.

An origin is the combination of the protocol, domain, and port from which your Ionic app or the external resource is served. For example, apps running in Capacitor have capacitor://localhost (iOS) or http://localhost (Android) as their origin.

In order to know if an external origin supports CORS, the server has to send some special headers for the browser to allow the requests.

When the origin where your app is served (e.g. http://localhost:8100 with ionic serve) and the origin of the resource being requested (e.g. https://api.example.com) don’t match, the browser’s Same Origin Policy takes effect and CORS is required for the request to be made.

CORS errors are common in web apps when a cross-origin request is made but the server doesn’t return the required headers in the response (it’s not CORS-enabled):

XMLHttpRequest cannot load https://api.example.com. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8100’ is therefore not allowed access.

Depending on the type of request the app tries to make, the browser will need to send a preflight request ahead of time in order to know if the external resource supports CORS and if the actual request can be sent safely. If a preflight isn’t needed—like in the case of some simple GET, POST or HEAD requests— the app’s request will be made right away.

It can be hard to remember all the different CORS headers, what they do, which go in the app versus which go in the server, and if a request is considered simple or if a preflight request is needed.

That’s why, I gathered all of the common questions and issues from GitHub, the forum, and Slack to contribute a new CORS Errors section to the Ionic documentation. It will not only help you to understand CORS better and troubleshoot problems, but it can also be a guide for recommended solutions and best practices depending on your specific scenario. Hope it’s helpful!

Check out the new CORS Errors page in the docs and let us know what you think!

Signup for the Ionic Newsletter to get the latest news and updates!