title: Cross Domain ajax OPTIONS error 403 (Django)
body: <p>I'm developing some site aaa.com with django, which sends cross-domain ajax "GET" requests to receive json data from bbb.com which is also running on django and is using REST framework. At this point everything works pretty fine with adding  <code>crossDomain: true; withCredentials:true</code>. And of course its configurated on server-side of aaa.com.<br>
  <code>...-Allow-Credentials: true; 
  ...-Allow-Origin: bbb.com</code></p>
  
  <p>The main issue comes when aaa.com is trying to make <code>PUT POST DELETE</code> ajax requests.
  According to CORS documentation: 
  [<a href="https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0]" rel="nofollow">https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0]</a>, client side ajax request is correct, and<br>
  <code>...-Allow-Headers, ...-Allow-Methods</code><br>
  is matched with<br>
  <code>...-Request-Headers, ...-Request-Methods</code></p>
  
  <p>so this request is not 'simple' and first of all browser sends preflight request from aaa.com to bbb.com to ask if some custom headers and methods are allowed. </p>
  
  <p>Everything is OK But I'm still getting 403 Error. Here is the request/response:</p>
  
  <pre><code>General:
  Request URL:http://bbb.com/api/someapipage/
  Request Method:OPTIONS
  Status Code:403 Forbidden
  Remote Address:some ip:80
  
  Response Headers:
  Access-Control-Allow-Credentials:true
  Access-Control-Allow-Headers:accept, content-type, x-csrftoken, x-requested-with
  Access-Control-Allow-Methods:GET, POST, OPTIONS, HEAD, PUT, DELETE
  Access-Control-Allow-Origin:http://aaa.com
  Allow:GET, POST, HEAD, OPTIONS
  Connection:Keep-Alive
  Content-Language:en
  Content-Type:application/json
  Date:Mon, 04 Jul 2016 14:20:38 GMT
  Keep-Alive:timeout=5, max=100
  Server:gunicorn/19.6.0
  Transfer-Encoding:chunked
  Vary:Accept,Accept-Language,Cookie
  X-Frame-Options:SAMEORIGIN
  
  Request Headers:
  Accept:*/*
  Accept-Encoding:gzip, deflate, sdch
  Accept-Language:en-US,en;q=0.8,ru;q=0.6
  Access-Control-Request-Headers:accept, content-type, x-csrftoken
  Access-Control-Request-Method:POST
  Connection:keep-alive
  Host:aaa.com
  Origin:http://aaa.com
  Referer:http://aaa.com/
  User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
  </code></pre>
  
  <p>After week of tries to fix this issue I realised that server wants to Vary: Cookie on pre-flighted request which is impossible because cross-domain pre-flight request cannot contain cookie in its header.</p>
  
  <p>I started finding some solution to this issue and found:
  <a href="https://code.djangoproject.com/ticket/13217" rel="nofollow">https://code.djangoproject.com/ticket/13217</a></p>
  
  <p>"Enabling django.middleware.locale.LocaleMiddleware causes that django adds a 'Vary: Cookie' header to every reponse."
  So localMiddleware adds header Vary: Cookie even in pre-flight OPTIONS response</p>
  
  <p>There are lots of reccomendations to use <code>djang-cors-header</code> to fix some of this problems. But using this package function are equal to my settings on server-side.</p>
  
  <p>I have also found pretty package: <code>django-dont-vary-on</code> which if installed can set decorators to turn off Vary:cookie, but in my case i need to turn off Vary:cookie only in OPTIONS response.</p>
  
  <p>Im bit new to django and actually cannot even imagine what to do in this situation. Every my step is just like walking on a mine field. 
  Is there any solution or some alternatives?</p>