Home > OS >  Django backend on port 8083 can't parse AJAX CORS POST request served from gulp web page on por
Django backend on port 8083 can't parse AJAX CORS POST request served from gulp web page on por

Time:12-21

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

CodePudding user response:

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