Access-Control-Allow-Origin in Django app

Question:

I’m developing a Phonegap app for my Django based app, but when trying to make Ajax calls I get this error:

XMLHttpRequest cannot load http://domain.herokuapp.com/getcsrf/?tags=jquery%2Cjavascript&tagmode=any&format=json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 

How can I make it so my Django app allows cross origin for some urls?

Here’s my Ajax code:

get: function() {
    $.getJSON("http://domain.herokuapp.com/getcsrf/",
    {
        tags: "jquery,javascript",
        tagmode: "any",
        format: "json"
    },
    function(data) {
        $.each(data.items, function(item){
            console.log(item);
            });
    });
}
Asked By: Sascuash

||

Answers:

Django by default does not provide the headers necessary to provide cross origin. The easiest way would be to just use this Django app that handles it for you: https://github.com/adamchainz/django-cors-headers

  • Add to installed apps
  • Add to middleware
  • Then stuff like…
CORS_ALLOWED_ORIGINS = [
    "http://read.only.com",
    "http://change.allowed.com",
]

to support allowing all, just use the setting…
CORS_ALLOW_ALL_ORIGINS = True
and then do any filtering of the request in middleware or in the view.

Answered By: stormlifter

For single views you can manually add headers:

@require_GET
def api_getto(request):
    response = JsonResponse(
        # your stuff here
    )
    response["Access-Control-Allow-Origin"] = "*"
    response["Access-Control-Allow-Methods"] = "GET, OPTIONS"
    response["Access-Control-Max-Age"] = "1000"
    response["Access-Control-Allow-Headers"] = "X-Requested-With, Content-Type"
    return response
Answered By: mariusz_latarnik01

In my case I was posting a file more than 1 mb and I was getting this error because of nginx configration (default max size 1 mb) So……

For me path of nginx.conf was /etc/nginx/nginx.conf.

In my case I just added client_max_body_size in http block and it worked for me

http {
    ...
    client_max_body_size 200M;
}    

Make sure to restart nginx after changing this config

Answered By: Zohab Ali

You can use "django-cors-headers". Simply install it using pip:

    pip install django-cors-headers

Add ‘corsheaders’ to your installed apps:

    INSTALLED_APPS = [
        ...
        'corsheaders',
        ...
    ]

Add middleware:

    MIDDLEWARE = [
        ...,
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        ...,
    ]

Then add this to your "settings.py":

    CORS_ALLOWED_ORIGINS = [
        'http://siteyouwantto.allow.com',
        'http://anothersite.allow.com',
    ]

If you also want to allow some domains to make "POST" requests, add this to your "settings.py" and don’t forget to add it in "CORS_ALLOWED_ORIGINS".

    CSRF_TRUSTED_ORIGINS = [
        'http://siteyouwantto.allow.com',
    ]

I hope this resolves your issue 🙂

Answered By: Pranava Mohan

You can use django-cors-headers as others have suggested, as of writing this you’ll need to follow all the steps below.

To use django-cors-headers in your project, follow the guide in the Setup and Configuration sections of the cors headers project’s README, or read it below (I’ve copied from the README for convenience).


SETUP

Install from pip:

python -m pip install django-cors-headers

and then add it to your installed apps:

INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]

Make sure you add the trailing comma or you might get a ModuleNotFoundError (see this blog post).

You will also need to add a middleware class to listen in on responses:

MIDDLEWARE = [
    ...,
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...,
]

CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django’s CommonMiddleware or Whitenoise’s WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.

Also if you are using CORS_REPLACE_HTTPS_REFERER it should be placed before Django’s CsrfViewMiddleware.


CONFIGURATION

Configure the middleware’s behaviour in your Django settings. You must set at least one of three following settings:

`CORS_ALLOWED_ORIGINS`
`CORS_ALLOWED_ORIGIN_REGEXES`
`CORS_ALLOW_ALL_ORIGINS`

CORS_ALLOWED_ORIGINS

A list of origins that are authorized to make cross-site HTTP requests. Defaults to [].

An Origin is defined by the CORS RFC Section 3.2 as a URI scheme + hostname + port, or one of the special values ‘null’ or ‘file://’. Default ports (HTTPS = 443, HTTP = 80) are optional here.

The special value null is sent by the browser in "privacy-sensitive contexts", such as when the client is running from a file:// domain. The special value file:// is sent accidentally by some versions of Chrome on Android as per this bug.

Example:

CORS_ALLOWED_ORIGINS = [
    "https://example.com",
    "https://sub.example.com",
    "http://localhost:8080",
    "http://127.0.0.1:9000"
]

Previously this setting was called CORS_ORIGIN_WHITELIST, which still works as an alias, with the new name taking precedence.

CORS_ALLOWED_ORIGIN_REGEXES

A list of strings representing regexes that match Origins that are authorized to make cross-site HTTP requests. Defaults to []. Useful when CORS_ALLOWED_ORIGINS is impractical, such as when you have a large number of subdomains.

Example:

CORS_ALLOWED_ORIGIN_REGEXES = [
    r"^https://w+.example.com$",
]

Previously this setting was called CORS_ORIGIN_REGEX_WHITELIST, which still works as an alias, with the new name taking precedence.

CORS_ALLOW_ALL_ORIGINS

If True, all origins will be allowed. Other settings restricting allowed origins will be ignored. Defaults to False.

Setting this to True can be dangerous, as it allows any website to make cross-origin requests to yours. Generally you’ll want to restrict the list of allowed origins with CORS_ALLOWED_ORIGINS or CORS_ALLOWED_ORIGIN_REGEXES.

Previously this setting was called CORS_ORIGIN_ALLOW_ALL, which still works as an alias, with the new name taking precedence.

Answered By: orangecaterpillar
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.