Django backend on port 8083 can’t parse JQuery AJAX CORS POST request served from gulp web page on port 8081

Welcome to Programming Tutorial official website. Today - we are going to cover how to solve / find the solution of this error Django backend on port 8083 can’t parse JQuery AJAX CORS POST request served from gulp web page on port 8081 on this date .

On Linux Debian Bullseye, I am running a gulp HTML server on port 8081, and a Django backend on port 8083. I am trying to POST a relatively large JSON document from a static page using JQuery’s AJAX feature. After properly setting up the django-cors-headers module, with MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware" ] , CORS_ALLOWED_ORIGINS and CSRF_TRUSTED_ORIGINS on settings.py, I coded the following HTML view on views.py, with the @csrf_exempt decorator in place since I’m running everything on localhost:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def processOrder(request):
   leasing_order_unicode = request.body.decode("utf-8")
   print(request.POST.__dict__)
   print(request.POST["leasing_order"])
   return HttpResponse(leasing_order_unicode, headers={ "Access-Control-Allow-Origin": "http://localhost:8081", "Content-Type": "application/json" })

Then I added it to urls.py as follows:

path("processorder", processOrder, name="processorder")

I expect my Django view to be able to access the JSON string with request.POST["leasing_order"]. Instead, I get errors and failures when attempting to access it.

Let serializedata() be a function that takes care of gathering all my local data into an object and then serializing it. If I POST my form data with multipart/form-data encoding as follows:

export function sendOrder_multipart()
{
   let finalorder = serializedata();
   let finalorder_postdata = new FormData();
   finalorder_postdata.append("leasing_order", finalorder);
   $.ajax({ method: "POST", url: "http://localhost:8083/orderstable/processorder",
      data: finalorder_postdata, processData: false, contentType: "multipart/form-data" });
}

I get the following error on my Django backend’s console output:

Bad request (Unable to parse request body): /orderstable/processorder
Traceback (most recent call last):
  File "<project path>/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "<project path>/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "<project path>/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "<project path>/<website>/orderstable/views.py", line 54, in processOrder
    print(request.POST.__dict__)
  File "<project path>/lib/python3.9/site-packages/django/core/handlers/wsgi.py", line 102, in _get_post
    self._load_post_and_files()
  File "<project path>/lib/python3.9/site-packages/django/http/request.py", line 328, in _load_post_and_files
    self._post, self._files = self.parse_file_upload(self.META, data)
  File "<project path>/lib/python3.9/site-packages/django/http/request.py", line 287, in parse_file_upload
    parser = MultiPartParser(META, post_data, self.upload_handlers, self.encoding)
  File "<project path>/lib/python3.9/site-packages/django/http/multipartparser.py", line 76, in __init__
    raise MultiPartParserError('Invalid boundary in multipart: %s' % force_str(boundary))
django.http.multipartparser.MultiPartParserError: Invalid boundary in multipart: None
[17/Dec/2021 20:29:11] "POST /orderstable/processorder HTTP/1.1" 400 143

If I tweak my Javascript frontend’s function to not use multipart/form-data encoding, like this:

function sendOrder_nomultipart()
{
   let finalorder = serializedata();
   let finalorder_postdata = new FormData();
   finalorder_postdata.append("leasing_order", finalorder);
   $.ajax({ method: "POST", url: "http://localhost:8083/orderstable/processorder",
      data: finalorder_postdata, processData: false });
}

I get a slightly different result, but still can’t access my string through request.POST:

{'_encoding': 'UTF-8', '_mutable': False}
Internal Server Error: /orderstable/processorder
Traceback (most recent call last):
  File "<project root>/lib/python3.9/site-packages/django/utils/datastructures.py", line 83, in __getitem__
    list_ = super().__getitem__(key)
KeyError: 'leasing_order'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<project root>/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "<project root>/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "<project root>/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "<project root>/<website>/orderstable/views.py", line 55, in processOrder
    print(request.POST["leasing_order"])
  File "<project root>/lib/python3.9/site-packages/django/utils/datastructures.py", line 85, in __getitem__
    raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'leasing_order'
[17/Dec/2021 20:35:59] "POST /orderstable/processorder HTTP/1.1" 500 106954

Answer

I found the solution after reproducing this issue with a minimum test case. To solve this issue, you must pass the POST data into $.ajax() as a simple object instead of using a FormData() object, and omit the contentType and processData fields of the configuration object.

Code that worked:

function sendOrder_thegoodone()
{
   let finalorder = serializedata();
   let finalorder_obj = { leasing_order: finalorder };
   $.ajax(
   { 
      method: "POST", 
      url: "http://localhost:8083/orderstable/processorder",
      data: finalorder_obj
   });
}