简体   繁体   中英

Access-Control-Allow-Origin in Django app

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);
            });
    });
}

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.

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

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 :)

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM