3

I'm trying to make a simple API using Django. I have setup a django server, and then on my own html file I send requests using $.getJSON. So far it's been working using the django cors headers package.

Now I've been trying to send a request header to my django server, but I'm getting this error in the Chrome console:

Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/?q=example+query' from origin 'http://localhost:63342' has been blocked by CORS policy: Request header field Example-Header is not allowed by Access-Control-Allow-Headers in preflight response.

I'm not sure what's the problem, I have django-cors setup correctly and I am able to make requests, I'm just not allowed to set request headers.

Setup:

INSTALLED_APPS = [
    ...
    'corsheaders',
]
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]
CORS_ALLOWED_ORIGINS = [
    "http://localhost:63342"
]
<script>
   $.ajaxSetup({
      beforeSend: function(request) {
         request.setRequestHeader("Example-Header", 'Example-Value');
      },
   });
   $.getJSON("http://127.0.0.1:8000/api/?q=example+query", function (data) {
      console.log(data);
   });
</script>
@cache_page(60 * 60 * 24 * 7)
def ExampleAPI(request):
    if request.method == 'GET':
       print(request.headers['Example-Header']) # Print Header Value 
       print(request.GET.get('q')) # Print URL Query Parameter Value   
       return JsonResponse([{"Example-Response": "Example-Response-Value"}], safe=False) 

So what am I doing wrong? Does django-cors not support this? I tried looking it up but I could not find anything. Thanks.

John Doe
  • 512
  • 1
  • 5
  • 17

2 Answers2

5

From documentation for django-cors-headers on PyPI it looks like you need to set the CORS_ALLOW_HEADERS like so:

CORS_ALLOW_HEADERS = [
    ...
    "Example-Header",
    ...
]

https://pypi.org/project/django-cors-headers/

If you want to dive deeper into CORS here is a thorough documentation: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

  • Setting this in Django 3 (probably any version of Django) does not cause a response header of "Access-Control-Allow-Headers" to be returned. – Dave Jul 09 '22 at 21:54
  • The question was for the Django app to accept the header not respond with one. For that case indeed the CORS_ALLOW_HEADER wont work. See the response by Sqyed Mostafa – BeeDeeBePope Aug 02 '22 at 09:40
  • Thank you very much, I was missing this setting on my `settings.py` file. I just had to add all the headers that I was sending on the front-end. – Dan Mar 27 '23 at 06:58
2

For me CORS_ALLOW_HEADERS didn't work.

after try couple of things I found out CORS_EXPOSE_HEADERS would work.

CORS_EXPOSE_HEADERS = [
    "my-custom-header",
]

this means now I can set 'my-custom-header' (with its value) in response header.

  • Good to know, though the question was for the Django app to accept a header not respond with one. – BeeDeeBePope Aug 02 '22 at 09:41
  • that's not a 'good thing to know', CORS_ALLOW_HEADERS didn't work for me, CORS_EXPOSE_HEADERS did. – Seyed Mostafa SeyedAshoor Aug 02 '22 at 13:08
  • 1
    You are talking about two connected, but slightly different, concepts in CORS. Take a look at this post https://stackoverflow.com/questions/28107459/in-the-http-cors-spec-whats-the-difference-between-allow-headers-and-expose-he – BeeDeeBePope Aug 02 '22 at 16:53
  • yea, you're right -Access-control-expose-headers: cause the client to be able to access some headers specified in this (from the response header) -Access-control-allow-headers: specifies which headers are allowed to change the state of the server. – Seyed Mostafa SeyedAshoor Aug 02 '22 at 17:50