: I provide a practical solution for solving CORS issue in in Ionic and Cordova. The solution works both for iOS and Android. Summary WKWebView Image credit: http://enzolutions.com If you code with Ionic or Cordova and use a REST API, you probably have seen an error like this: XMLHttpRequest cannot load http://api.ionic.com/endpoint. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8100' is therefore not allowed access. What is CORS? CORS stands for Cross Origin Resource Sharing. In short, CORS is a method to prevent a client to request a display a service from a host other than the one that is currently showing. This is done for security reasons. The Problem In order for an external API server to work in the presence of CORS, it should include something like this in its header: Access-Control-Allow-Origin: * The problem however is that some API providers do not include this and since we don’t have any control over the server, we cannot add this to the response header. This is a huge problem specially in iOS where Ionic and Cordova run in , which enforces CORS. WKWebView Solutions Ionic’s blog has an . Unfortunately, the solution that they provide is only suitable when you are running the app using ionic serve or ionic run -l. That solution will not work on the production release! old post on CORS issues The good news is that you can still solve the problem by doing a tiny little bit of work. I list a couple of solutions: the idea is simple: create your OWN server in the middle of your client and the main API server. Your client request goes to your own server, which support CORS. Your server sends the request to the API server, gets the results, and sends it back to you. Using a proxy (Not a good solution): Your server can be as simple as reading requests from specific node like from a database server like Google Firebase, and then write the results in another node called . /requests /replies While this is doable, I don’t like this solution cause you will need to create a new server and maintain it. : Fortunately Cordova’s comes to rescue. Since this plugin’s HTTP requests don’t go through WKWebView, it does not have CORS issues. This is awesome! 2. Use Native HTTP (My favorite) native HTTP plugin So the solution is to send the HTTP requests for the given API through native HTTP plugin rather than NodeJS’s requests. Therefore: Instead of using npm’s Request or Fetch packages, use Cordova’s plugin. Solution: Here is an example usage for using Cordova’s native HTTP: Binance’s REST API declare cordova: any; url = ; params = {}; headers = {}; cordova.plugin.http.get(url, params, headers, (response) => { .log(response.status); }, { .error(response.error); }); var let 'https://api.binance.com/api/v1/exchangeInfo' let let console ( ) function response console What if we are using an npm wrapper for the API? The above solution worked because we were using a simple REST HTTP call. However, sometimes an API call is more complex. For example, you have to provide APIKey and Secret and sign the request. For such complex requests there are some npm wrappers that do the job and take care of the more complex issues, except that those packages use npm’s Request or Fetch packages. Depending on the npm wrapper that you use, there are two possible conditions: 1. The Request or Fetch function is exposed in the constructor If you are lucky, some npm packages like already allow you to overload their Fetch request function. In this case all you need is to pass your own HTTP Fetch wrapper to its constructor: CCXT exchange = ccxt[ ]({ : , :apiKey, : secret, fetchImplementation: ccxtFetchImplementation }); ccxtFetchImplementation(url, options) { headers = options.headers || ; ( (resolve, reject) => { cordova.plugin.http.get(url, {}, headers, { response.text = { ( { resolve(response.data); }) } response.headers = ( .entries(response.headers)); response.statusText = response.statusMessage; resolve(response); }, { .log( , response.error); reject(response); }); }) } //First overload fetchImplementation in the constructor let new "poloniex" enableRateLimit true apiKey secret //Overloaded function that uses Native http calls // ------> My wrapper function //Define ccxtFetchImplementation definition in your IONIC program: let undefined return new Promise async //Cordova native http get request ( ) function response //CCXT needs this function to match npm Fetch => () return new Promise ( ) => resolve, reject //Use Map to mimic npm Fetch that is used by ccxt new Map Object ( ) function response console 'response.error: ' 2. The Request or Fetch function is NOT exposed in the constructor But if you are not lucky, the Fetch request function is not exposed in the constructor. For example here is a . But it uses npm’s Request package which causes CORS issue, sigh… great npm wrapper for Binance’s API In this case the solution is not too hard: you just need to modify that package and force it to use Cordova’s Request rather than npm’s. For example, I such that instead of its default npm Request, it takes the Request function from constructor, which I set it to cordova.plugin.http.get : modified Binance’s npm wrapper binanceRest = binanceApi.BinanceRest({ : apiKeySecret.apiKey, secret: apiKeySecret.secret, timeout: , recvWindow: , disableBeautification: , handleDrift: , : cordova.plugin.http.get }); const new key // Get this from your account on binance.com // Same for this 15000 // Optional, defaults to 15000, is the request time out in milliseconds 10000 // Optional, defaults to 5000, increase if you're getting timestamp errors false /* * Optional, default is false. Binance's API returns objects with lots of one letter keys. By * default those keys will be replaced with more descriptive, longer ones. */ false requestFunction // ----------> Added by me! /* Optional, default is false. If turned on, the library will attempt to handle any drift of * your clock on it's own. If a request fails due to drift, it'll attempt a fix by requesting * binance's server time, calculating the difference with your own clock, and then reattempting * the request. */ So in short, if you are using an npm wrapper for a REST API that doesn’t expose its HTTP request function in its constructor: Create a branch of that wrapper on Github in your own GithubModify that package and force it to use Cordova’s HTTP requestUse the modified package in your Ionic program The caveat is that if the npm wrapper is updated you will need to integrate the updates in your branch. But perhaps you can create a pull request and encourage the package owner to use your updates and expose the request function in the constructor. If you liked this article, please give me feedback if this solution solved your issue. Also, please try my app that is written in Ionic: . It is one of the most comprehensive alerting and portfolio management apps for cryptocurrency traders. Bitcoin CrazYness