Django 4.0.1中AJAX POST上传文件无法通过request.FILES获取问题
问题原因及解决方案
核心原因:AJAX请求的contentType配置错误
你在jQuery的AJAX配置里写了:
ContentType: "application/x-www-form-urlencoded",
这里存在两个关键问题:
- 属性名大小写错误:jQuery的AJAX选项中,该属性为小写的
contentType,大写的ContentType不会被框架识别。 - 值设置错误:上传文件时,请求的Content-Type必须为
multipart/form-data,且需要包含自动生成的boundary分隔符。手动设置application/x-www-form-urlencoded会导致后端无法解析文件数据,最终request.FILES为空。
另外,当使用FormData作为AJAX的data参数时,jQuery会自动正确设置contentType(包括boundary),因此无需手动配置该属性,直接删除即可。
其他可优化的细节
- 无需手动添加
HTTP_X_REQUESTED_WITH头:jQuery发起AJAX请求时,默认会自动添加X-Requested-With: XMLHttpRequest头,可从headers中移除该键以简化代码。 - CSRF Token的更优传递方式:除了放在headers里,也可以直接将CSRF Token添加到FormData中,示例如下:
这种方式更符合Django的常规用法,同时无需单独设置headers里的form_data.append('csrfmiddlewaretoken', csrf_token);X-CSRFToken。
修正后的JavaScript代码
$(document).ready(function (e) { $('#upload').on('click', function (event) { event.preventDefault() var form_data = new FormData(); var ins = document.getElementById('multiFiles').files.length; if(ins == 0) { $('#msg').html('<span style="color:red">Select at least one file</span>'); return; } for (var x = 0; x < ins; x++) { form_data.append("files[]", document.getElementById('multiFiles').files[x]); } // 将CSRF Token添加到FormData中 csrf_token = $('input[name="csrfmiddlewaretoken"]').val(); form_data.append('csrfmiddlewaretoken', csrf_token); $.ajax({ type: 'POST', url: '/docs/', dataType: "json", cache: false, processData: false, // 移除错误的ContentType配置 data: form_data, success: function (response) { console.log("successssssssssssss") }, error: function (response) { console.log("NOPEEEEEE") } }); }); });
后端代码验证
你的后端代码逻辑本身没有问题,修正前端请求后,request.FILES.getlist('files[]')即可正确获取到上传的文件列表。
内容的提问来源于stack exchange,提问作者Wincij
相关产品推荐
相关产品推荐

