foske
foske

Reputation: 106

How to send an "Access-Control-Allow-Origin" header using Django 3?

I'm new to server-side programming and I'm trying to get some information from the backend through the frontend. The backend, as indicated in the header, is written in Django. The frontend is written in React, if it's important.

There is a view function on the backend, which only returns plain string:

 HttpResponse("Some useful information.")

This string is available at: "http://localhost:8000/info/". I checked through the browser, it really works.

So, I'm trying to get this string from the frontend, using axios library:

axios.get("http://localhost:8000/info/").then(res => {
    console.log(res.data);
})

An error occurs, when I'm trying to send request. It sounds like this:

Access to XMLHttpRequest at 'http://localhost:8000/info/' from origin 'http://localhost:3006' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

There are no errors on the server side. It returns code 200.

As far as I understand, the data are received on the frontend, but the browser blocks access to it, because the server must additionally attach an 'Access-Control-Allow-Origin' header.

How can I send this header from the server? Should I configure something in the settings.py or modify the view function? Or maybe there is another solution?

Upvotes: 1

Views: 5471

Answers (3)

Nico Griffioen
Nico Griffioen

Reputation: 5405

Your browser doesn't allow the web application to perform requests to a different origin (scheme, host or port) as a security measure. So if your frontend is served from for instance localhost:5000, you won't be able to access your Django instance on localhost:8000.

If your server specifies Access-Control-Allow-Origin header, your browser will accept a request like this.

Django does not by default add this header, but you can write a middleware for it yourself, or you can use the django-cors-headers package to do it for you.

Install this package, then add it to your INSTALLED_APPS:

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

and add its middleware:

MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

You can then either set CORS_ORIGIN_ALLOW_ALL in your settings to True (Not recommended for production environments)

Or set CORS_ORIGIN_WHITELIST to ['http://localhost:8000']

Upvotes: 0

Alasdair
Alasdair

Reputation: 308899

In Django, you can set a header by modifying the response before you return it.

response = HttpResponse("some useful information")
response["Access-Control-Allow-Origin"] = "http://localhost:3006"
return response

In practice, if you want to send the CORS header for multiple views, then I would suggest using django-cors-headers. It has a middleware which sets the header.

Upvotes: 1

Kevin Christopher Henry
Kevin Christopher Henry

Reputation: 48952

The browser's Same Origin Policy is preventing your script from reading the data.

To allow that you need to implement Cross-Origin Resource Sharing.

To do that in Django, use the django-cors-headers package.

Upvotes: 2

Related Questions