端口 8083 上的 Django 后端无法解析从端口 8081 上的 gulp 网页提供的 JQuery AJAX CORS POST 请求

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

在 Linux Debian Bullseye 上,我是 运行 端口 8081 上的 gulp HTML 服务器和端口 8083 上的 Django 后端。我正在尝试 POST 来自静态页面的相对较大的 JSON 文档,使用 JQuery 的 AJAX 功能。在正确设置 django-cors-headers 模块后,MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware" ]CORS_ALLOWED_ORIGINSCSRF_TRUSTED_ORIGINS 在 settings.py 上,我在 [=] 上编写了以下 HTML 视图48=],使用 @csrf_exempt 装饰器,因为我 运行 本地主机上的所有内容:

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" })

然后我把它添加到urls.py如下:

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

我希望 我的 Django 视图能够使用 request.POST["leasing_order"] 访问 JSON 字符串。 相反, 我在尝试访问它时遇到错误和失败。

serializedata() 成为一个函数,负责将我所有的本地数据收集到一个对象中,然后将其序列化。如果我POST我的表单数据用multipart/form-data编码如下:

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" });
}

我在 Django 后端的控制台输出中收到以下错误:

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

如果我将 Javascript 前端的功能调整为不使用 multipart/form-data 编码,如下所示:

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

我得到的结果略有不同,但仍然无法通过 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

我在用最少的测试用例重现此问题后找到了解决方案。要解决此问题,您必须将 POST 数据作为简单对象传递到 $.ajax() 中,而不是使用 FormData() 对象,并省略 contentTypeprocessData配置对象的字段。

有效代码:

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