Enabling CORS in Angular JS

Note: This post covers how to enable CORS with AngularJS<1.2. Apparently in the latest AngularJS versions you don't have to add anything to make it work.

I was recently experimenting with building an API with django-tastypie and make it accessible via CORS, so it can be used from a different host from an AngularJS app.

For the Django part it was relatively straightforward. I could have either written my own Middleware, dealing with incoming CORS requests, but decided to use django-cors-headers in the end. Following the instructions in the github repo and adding my host where AngularJS is hosted to the CORS_ORIGIN_WHITELIST setting did enable the Django server to handle CORS.

With AngularJS it was a little more tricky, mainly because information is spread all over the web. Beside the fact that I was trying to implement a service using ngResource to communicate with the API, the following did enable AngularJS to send its requests with the appropriate CORS headers globally for the whole app:

var myApp = angular.module('myApp', [
    'myAppApiService']);

myApp.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
    }
]);

_

Just setting useXDomain to true is not enough. AJAX request are also send with the X-Requested-With header, which indicate them as being AJAX. Removing the header is necessary, so the server is not rejecting the incoming request.

16 Comment(s)

Migrating to Heroku

To cut some personal costs and simply because I was interested in it, I recently moved this blog to Heroku, the popular cloud hosting platform.

Since 2011 Heroku officially supports Python deployments. Running on a single dyno it is even for free. Following the official guide to deploy a Django application, the transition from my VPS to Heroku was pretty straight-forward and easy. Additionally Heroku enforces good practices, like using virtualenv, and supports more and more popular technologies, like the Python WSGI server Gunicorn.

Following a short general guide of what had to be done from my side to do the transition:

  • Create a fixture file from your database via the dumpdata command.
  • Since I didn't want to add any billing information to Heroku yet, I had to rewrite everything related to sending emails from my web server, to save the incoming contact request in the database instead. That was pretty much just the creation of a new model and a one-liner to save it to the DB instead of sending an email,
  • Already using virtualenv, the rest was simply adding or changing requirements. In addition of removing the MySQL bindings for python I added the following libaries:

    dj-database-url==0.2.1
    django-heroku-memcacheify==0.4
    django-pylibmc-sasl==0.2.4
    gevent==0.13.8
    greenlet==0.4.0
    gunicorn==0.17.2
    psycopg2==2.4.6
    pylibmc==1.2.3
    

  • Static files are served via Django directly for the time being, since a Web-Dyno using Python can not serve them the normal way. I will move them to be served by a solution like Amazon S3 in the future. Therefore I added the following to my urlconf:

    urlpatterns += patterns(
        '',
        url(r'^media/(?P.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
    )
    

  • Running the dyno via Gunicorn with gevent support was a single line in the Procfile:

    web: gunicorn -k gevent wsgi:application

  • Finally:

    git push heroku master

So far I am quite happy with Heroku. I didn't recognize any differences to previous VPS hosting and I don't have to deal with server maintenance anymore, even it was an experience I don't want to miss. Goodbye VPS, welcome Heroku!

7 Comment(s)

django-urli18n

Even I released django-urli18n already two weeks ago, I didn't find the time to actually announce it. So here it is:

What is django-urli18n?

A reusable Django app to display the current activated language in the URL.

Features

- different ways to show the language in the URL: in the path (for example www.example.com/en/home/) or in a query string (for example www.example.com/home/?lang=en)

- simple to use and include into new or existing Django projects

Where to get it?

Check out the project page on Github.

2 Comment(s)