如何将页面图片通过模态框按钮发送至Django服务器?
解决方法
核心思路
因为表单结构限制,咱们可以用JavaScript + FormData绕开传统表单,直接构造请求上传图片:先拿到目标图片的数据,打包成FormData对象,再通过AJAX请求发送到Django后端接口。
具体实现
1. 前端代码(JavaScript)
给模态框里的上传按钮绑定点击事件,完成图片数据的获取与发送:
// 获取关键DOM元素 const sendBtn = document.getElementById('sendBtn'); const targetImage = document.getElementById('my-image'); sendBtn.addEventListener('click', async () => { let imageFile; // 分两种情况处理图片数据: // 情况1:图片是用户通过隐藏的file input选择的(比如点击图片触发文件选择) // 假设你有隐藏的<input type="file" id="hiddenFileInput" style="display:none;"> // 此时直接取input的文件对象: // const fileInput = document.getElementById('hiddenFileInput'); // imageFile = fileInput.files[0]; // 情况2:图片是服务器上已存在的资源(src是服务器路径),需要转成Blob再封装成File const imgResponse = await fetch(targetImage.src); const imgBlob = await imgResponse.blob(); imageFile = new File([imgBlob], 'uploaded-img.jpg', { type: imgBlob.type }); // 构造FormData,用来传递文件数据 const formData = new FormData(); formData.append('uploaded_image', imageFile); // 'uploaded_image'要和后端接收的字段名一致 // 发送POST请求到Django后端 try { const uploadResponse = await fetch('/upload-image/', { method: 'POST', headers: { // 必须携带Django要求的CSRF令牌 'X-CSRFToken': getCsrfToken() }, body: formData }); if (uploadResponse.ok) { alert('图片上传成功'); // 这里可以加关闭模态框的逻辑 } else { alert('上传失败,请重试'); } } catch (err) { console.error('上传出错:', err); alert('上传过程出现异常'); } }); // 辅助函数:获取浏览器中的CSRF令牌 function getCsrfToken() { let token = null; 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; }
2. Django后端视图
编写视图函数接收并处理上传的图片:
from django.http import JsonResponse def upload_image(request): if request.method == 'POST': # 检查是否收到文件 if 'uploaded_image' not in request.FILES: return JsonResponse({'status': 'error', 'msg': '未收到图片文件'}, status=400) image_file = request.FILES['uploaded_image'] # 这里写图片的处理逻辑,比如保存到media目录 # 示例:用默认存储保存 from django.core.files.storage import default_storage saved_path = default_storage.save(f'uploads/{image_file.name}', image_file) return JsonResponse({'status': 'success', 'file_path': saved_path}) return JsonResponse({'status': 'error', 'msg': '仅支持POST请求'}, status=405)
3. 配置Django路由
在项目的urls.py中添加上传接口的路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('upload-image/', views.upload_image, name='upload_image'), ]
关键注意点
- CSRF令牌:Django默认开启CSRF保护,前端必须在请求头里携带
X-CSRFToken,否则请求会被拒绝,上面的getCsrfToken函数就是用来获取这个令牌的。 - 图片来源适配:如果是用户本地选择的图片,直接取file input的
files[0]即可,不用转Blob;如果是服务器上的图片,才需要通过fetch转成Blob再封装成File对象。 - 文件大小限制:Django默认限制上传文件大小,需要调整的话可以在
settings.py中修改FILE_UPLOAD_MAX_MEMORY_SIZE和MAX_UPLOAD_SIZE等参数。
内容的提问来源于stack exchange,提问作者dia05
相关产品推荐
相关产品推荐

