AJAX与Django多文件上传问题:如何从输入字段获取文件并加入请求数据
使用AJAX + Django实现多文件上传:获取并传递文件数据的正确姿势
嗨,我之前也踩过AJAX+Django多文件上传的坑,其实核心就是用FormData对象来处理二进制文件数据——普通JSON没法搞定这个。下面一步步给你讲清楚怎么实现:
1. 先调整HTML结构
确保文件输入框开启多文件选择功能,给它一个ID方便JS获取:
<!-- 多文件上传输入框,multiple属性允许选择多个文件 --> <input type="file" id="file-upload" name="files" multiple> <!-- 触发上传的按钮 --> <button id="upload-btn">上传文件</button>
2. 编写AJAX核心逻辑
这里的关键是用FormData包装文件数据,再通过AJAX发送给后端。注意不要手动修改contentType和processData,FormData会自动处理这些:
document.getElementById('upload-btn').addEventListener('click', function() { // 获取文件输入元素 const fileInput = document.getElementById('file-upload'); // 获取选中的所有文件(这是一个FileList对象) const selectedFiles = fileInput.files; // 创建FormData实例——这是处理文件上传的核心容器 const formData = new FormData(); // 逐个将文件添加到FormData中 for (let i = 0; i < selectedFiles.length; i++) { formData.append('files', selectedFiles[i]); // 如果需要额外传递其他字段,比如上传备注,可以这样加 // formData.append('remark', '这是一批测试文件'); } // 发送AJAX请求到Django后端 fetch('/api/upload-files/', { method: 'POST', headers: { // 必须带上Django的CSRF令牌,否则请求会被拒绝 'X-CSRFToken': getCsrfToken() }, body: formData }) .then(response => response.json()) .then(result => { console.log('上传成功:', result); // 这里可以添加上传成功后的UI逻辑,比如显示成功提示 }) .catch(error => { console.error('上传失败:', error); // 处理错误情况 }); }); // 辅助函数:从Cookie中获取Django的CSRF令牌 function getCsrfToken() { let token = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (const cookie of cookies) { const trimmedCookie = cookie.trim(); if (trimmedCookie.startsWith('csrftoken=')) { token = decodeURIComponent(trimmedCookie.substring('csrftoken='.length)); break; } } } return token; }
3. Django后端处理代码
后端通过request.FILES.getlist()获取所有上传的文件,注意要确保视图支持POST请求:
from django.http import JsonResponse from django.views.decorators.http import require_POST @require_POST def upload_files(request): # 获取所有上传的文件,参数要和JS中FormData.append的键一致 uploaded_files = request.FILES.getlist('files') # 处理每个文件,比如保存到服务器或数据库 saved_count = 0 for file in uploaded_files: # 示例:假设你有一个FileUpload模型,包含FileField字段 # FileUpload.objects.create(file=file) saved_count += 1 return JsonResponse({ 'status': 'success', 'message': f'成功上传{saved_count}个文件' })
几个必须注意的点
- CSRF令牌:Django默认会拦截没有CSRF令牌的POST请求,所以AJAX请求一定要带上
X-CSRFToken头,上面的辅助函数就是干这个的。 - FormData的append方式:上传多个文件时,要循环调用
append('files', file),而不是直接传数组,这样后端才能用getlist获取全部文件。 - 不要手动设置contentType:用FormData时,浏览器会自动设置正确的
multipart/form-data请求头,手动设置反而会导致后端无法解析文件。 - 大文件限制:如果要上传大文件,需要调整Django的
FILE_UPLOAD_MAX_MEMORY_SIZE和服务器的上传大小限制,避免请求被拦截。
内容的提问来源于stack exchange,提问作者Cariweb
相关产品推荐
相关产品推荐

