Fixing the Cordova browser platform Access-Control-Allow-Origin error

When developing a mobile app using Cordova or PhoneGap, the browser target platform can really speed up your development. You could serve the HTML files directly using cordova serve, but the browser platform, while being almost as fast, is much closer to the Android / IOS environments your app will eventually find itself in. It also has access to the Cordova APIs.

My general workflow is that I keep cordova run browser running in a terminal window (this will initially start a new instance of chrome), and periodically run cordova prepare browser as I’m developing. This last step packages up the “app”, along with the cordova.js bits, for the browser platform.

However, if your app contacts an external API or server at any point, for example with jQuery.ajax(), you will be greeted by the following error:

XMLHttpRequest cannot load http://some.api.com/api/endpoint. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8000' is therefore not allowed
access.

In short, your chrome browser is (wisely) refusing to access that outside resource (the API or server) for security reasons. If your browser did not do this, an attacker could quite easily access web services using your identity!

Reading up about this issue in the context of Cordova / PhoneGap, you’ll find the common solution to be either to modify the server that you’re accessing to allow explicitly this sort of cross-origin access, or to setup a proxy if the former is not possible. Often the former is indeed not possible (in my case, the app is talking to a hardware router API), but the latter is just way too much unnecessary effort.

The easy (but good) fix

Recall that cordova starts up a new instance of chrome which is only used to access your app. The app is completely under your control, so the risk of foul play by a third party is significantly reduced. Instead of setting up proxies, or changing servers, we could just instruct this special instance of chrome to ignore its cross-origin rules!

It took me a while to track this down, so here you go: Edit browser.js in yourapp/platforms/browser/cordova/node_modules/cordova-serve/src and change just the chromeArgs line so it looks like the one in the snippet below (you’re just adding the --disable-web-security argument):

function getBrowser(target, dataDir) {
    dataDir = dataDir || 'temp_chrome_user_data_dir_for_cordova';

    var chromeArgs = ' --user-data-dir=/tmp/' + dataDir + ' --disable-web-security';

Now make 100% sure that all of your Cordova chrome instances are stopped. The next time you do cordova run browser, note that the chrome window that appears has a yellow bar warning you about web security:

chrome-disable-web-security-warning.jpg

Only the special chrome instances started up by Cordova for apps where you have applied the above fix will have web-security disabled. By all means take note of the yellow warning, but also do enjoy all of your Cordova app requests successfully contacting the outside world!

Ubuntu 11.04 Natty Narwhal Annoyances (Dell E6410 with NVS 3100m GPU)

I recently upgraded my Dell E6410 with NVS 3100m GPU laptop from Ubuntu 10.10 (Maverick Meerkat) to 11.04 (Natty Narwhal), and I can’t shake this feeling that the distribution has taken a few steps back. I’m not even referring to the new Unity desktop, but to some super-irritating annoyances I had to fix or work around before being able to use the system. These annoyances were not present in 10.10, it had a whole different collection. 🙂

Wireless N connects, but no packets get through

The first annoyance was when I successfully connected to my wireless N access point, but couldn’t get a single packet through. After much searching, it turns out there’s a bug in the firmware for the Centrino Advanced-N 6200 wireless adapter that keeps it from getting any data through.

The solution is to disable wireless N on your laptop by creating a file etc/modprobe.d/inteldisablen.conf with the following contents:

options iwlagn 11n_disable50=1 11n_disable=1

and then to reboot. If you don’t want to reboot, just rmmod and modprobe the iwlagn kernel module. I’ve confirmed that this fix works.

Google Chrome scrolls excruciatingly slowly

After resuming and suspending, certain 2D and GPU-assisted graphics operations slow down. Scrolling in Chrome, even on a simple Google results page, is excruciatingly slow with head-explosion-levels of lag.

The solution is to disable hyperthreading, or at least to disable a number of CPU cores, at suspend and re-enable at resume. My laptop i5 CPU has 2 real cores, and thus 4 virtual cores due to hyperthreading. I’m using the following script, taken from this forum thread to do the necessary core disabling / enabling automatically:

#!/bin/sh

# Disable hyper-threading processor cores on suspend and hibernate, re-enable them
# on resume. Presumably helps for buggy nvidia behaviour.
# save this file as /etc/pm/sleep.d/20_core_i5_disable_cores and make excutable
# with chmod +x /etc/pm/sleep.d/20_core_i5_disable_cores

# from: http://www.nvnews.net/vbulletin/showthread.php?t=158091

case $1 in
        hibernate|suspend)
                echo 0 > /sys/devices/system/cpu/cpu1/online
                echo 0 > /sys/devices/system/cpu/cpu3/online
                ;;

        thaw|resume)
                echo 1 > /sys/devices/system/cpu/cpu1/online
                echo 1 > /sys/devices/system/cpu/cpu3/online
                ;;
esac

I’ve confirmed both the slow-down behaviour and the working of the fix.

Eclipse scrollbars don’t work

Natty’s new overlay scrollbars screw with Eclipse’s scrollbars, leaving you with 100% non-working scrollbars! You can either disable the overlay scrollbars completely, or comment out the GDK_NATIVE_WINDOWS line close to the start of the /usr/bin/eclipse shell script:

#export GDK_NATIVE_WINDOWS=true

On my setup, this fix works most of the time.

Conclusion

It’s a shame that these things don’t work out of the box, as some of them had been reported long before the Natty release. Before I forget, if you install 11.04 on this specific laptop, you might also have to follow my Ubuntu 10.10 howto if you see a black screen at bootup or resume.