Apache Cordova, Azure Mobile Apps and CORS

I am continuing my discovery of Apache Cordova to integrate it into Azure Mobile Apps. This post is about fixing a relatively minor issue. That issue is Cross-Origin Resource Sharing or CORS. One might think this is not an issue with Apache Cordova. After all, a mobile app should be able to access the remote data store with no problem. Where is the CORS issue? The issue occurs in two situations – when using cordova run browser and when using Ripple. In both cases, Apache Cordova starts a server on localhost to serve the pages. The client (the browser session) is pulling the pages from localhost, but retrieving the data from your Azure Mobile Apps service. This hits CORS.

The Server

I’ve got a simple server that is a copy of the basic app from the azure-mobile-apps samples directory. My server looks like this:

var express = require('express')(),
    morgan = require('morgan'),
    azureMobileApps = require('azure-mobile-apps');

var app = new azureMobileApps();

app.tables.initialize().then(function () {
    express.listen(process.env.PORT || 3000);

I have the following code in the tables/TodoList.js:

var table = require('azure-mobile-apps').table();

table.dynamicSchema = true;

module.exports = table;

You can find the complete code sample at my GitHub repository. I’ve deployed this to an Azure App Service using continuous deployment, linking my App Service to the GitHub repository.

The Client

I’ve adjusted my src/lib/storage-manager.js file as follows:

import uuid from 'uuid';
/* global OData */

export default class Store {
    constructor() {
        console.info('Initializing Storage Manager');

        // We need to add the ZUMO-API-VERSION to the headers of the OData request
        this._defaultHttpClient = OData.defaultHttpClient;
        OData.defaultHttpClient = {
            request: (request, success, error) => {
                request.headers['ZUMO-API-VERSION'] = '2.0.0';
                this._defaultHttpClient.request(request, success, error);

        this._service = 'https://ahall-todo-list.azurewebsites.net';
        this._store = `${this._service}/tables/TodoList`;

     * Read some records based on the query.  The elements must match
     * the query
     * @method read
     * @param {object} query the things to match
     * @return {Promise} - resolve(items), reject(error)
    read(query) {
        console.log('[storage-manager] read query=', query);

        var promise = new Promise((resolve, reject) => {
            /* odata.read(url, success(data,response), error(error), handler, httpClient, metadata); */

            var successFn = (data, response) => {
                console.info('[storage-manager] read data=', data);
                console.info('[storage-manager] read response=', response);
            var errorFn = (error) => {
                console.error('[storage-manager] read error=', error);

            OData.read(this._store, successFn, errorFn);
        return promise;

I’m using DataJS to do the actual call. Note that I’m not going to complete the call in this blog post – I’m just going to get past CORS. I’ve added the package to my npm install:

npm install --save datajs

I’ve also got a Gulp rule to copy the datajs library into my www/lib directory. Check out the GitHub repository to see how that works. I need to include the datajs library into my HTML page as well – that’s just a script reference. Now, let’s run the app and check out the console:


The Client Security Policy

There are a couple of places in Apache Cordova where you have to configure content security policies. The content security policy tells Apache Cordova where it can fetch data from. This is configured in two places – one of which is already done for you.

In config.xml, you will note the following line:

    <access origin="*" />

This tells Apache Cordova that the app should be able to access data from anywhere. But that isn’t the only place. In your index.html file – and any other HTML file you reference, there is a Content-Security-Policy tag:

        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">

Let’s recode this into a friendlier setting:

  • default-src
    • ‘self’
    • data: = Allow loading of local base64 values
    • gap: = Allow JS -> native communication on iOS
    • https://ssl.gstatic.com = Allow Talkback on Android
  • style-src
    • ‘self’ but don’t allow inline styles
  • media-src
    • Anywhere

You can read more about the Content-Security-Policy – it’s very flexible. For now, I need to add my URL to the default-src:

        <meta http-equiv="Content-Security-Policy" content="default-src 'self' https://ahall-todo-list.azurewebsites.net data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">

Handling CORS in Azure App Service

Before this will work, you also need to tell the server to trust your local instance. Log onto https://portal.azure.com and open up your web site. Click on Settings and find the CORS setting:


You can enter any URLs you want here. When I run cordova run browser, Apache Cordova will start a server at http://localhost:8000:


Don’t forget to save your changes once you are done.

Wrapping Up

Once you have done these changes, you can try the project again. This time the pre-flight connection will succeed. The actual transfer will succeed but the data decoding will not work. That’s because I haven’t finished writing the code for utilizing data.js as yet. That, however, is a blog post for another time.