如何用JavaScript/jQuery将用户选中文件夹复制到Django静态目录?
实现选中文件夹上传并复制到Django Static目录的方案
首先得明确:前端JavaScript无法直接操作服务器上的文件系统,所以我们需要结合「前端文件收集 + Django后端处理」的方式来完成这个需求。下面是完整的实现步骤:
1. 前端JavaScript处理:收集文件夹内的所有文件并上传
你的HTML输入框已经能选中文件夹了,接下来要在getfolder(event)函数里收集所有文件、保留原目录结构,然后通过AJAX发送给后端视图。
<!-- 你的原始输入框 --> <input type="file" id="files" name="files[]" onchange="getfolder(event)" webkitdirectory mozdirectory msdirectory odirectory directory multiple /> <output id="output"> <span id="file-list"></span> </output> <script> function getfolder(event) { const files = event.target.files; const fileList = document.getElementById('file-list'); const formData = new FormData(); // 清空之前的文件列表 fileList.innerHTML = ''; // 遍历所有选中的文件,添加到FormData,同时保留相对路径 for (let i = 0; i < files.length; i++) { const file = files[i]; // webkitRelativePath 会保留文件在原文件夹中的相对路径,比如"文件夹名/子文件夹/文件名.txt" formData.append('folder_files', file, file.webkitRelativePath); // 显示选中的文件路径到页面 const item = document.createElement('p'); item.textContent = file.webkitRelativePath; fileList.appendChild(item); } // 发送AJAX请求到后端 fetch('/upload-folder/', { method: 'POST', headers: { // 带上Django的CSRF令牌,避免跨站请求伪造 'X-CSRFToken': getCookie('csrftoken') }, body: formData }) .then(response => response.json()) .then(data => { if (data.success) { alert('文件夹已成功上传到static目录!'); } else { alert('上传失败:' + data.error); } }) .catch(error => { console.error('上传出错:', error); alert('上传过程中发生错误'); }); } // 辅助函数:获取CSRF令牌(Django需要这个验证) function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } </script>
2. Django后端处理:接收文件并复制到Static目录
接下来需要编写Django的视图函数和URL配置,处理前端发送的文件,按照原目录结构保存到static目录。
2.1 配置URL
在你的app的urls.py中添加一个上传路径:
from django.urls import path from . import views urlpatterns = [ # ... 其他URL path('upload-folder/', views.upload_folder, name='upload_folder'), ]
2.2 编写视图函数
在views.py中编写处理上传的逻辑:
import os from django.conf import settings from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt @csrf_exempt def upload_folder(request): if request.method == 'POST': # 获取上传的所有文件 uploaded_files = request.FILES.getlist('folder_files') # 目标目录:static下的uploaded_folders文件夹(可以自定义路径) target_base_dir = os.path.join(settings.STATIC_ROOT, 'uploaded_folders') try: # 确保目标目录存在 os.makedirs(target_base_dir, exist_ok=True) for file in uploaded_files: # 获取文件的相对路径,比如"my-folder/sub/file.txt" relative_path = file.name # 拼接完整的目标路径 target_path = os.path.join(target_base_dir, relative_path) # 创建文件所在的子目录(如果不存在) os.makedirs(os.path.dirname(target_path), exist_ok=True) # 写入文件到目标路径 with open(target_path, 'wb+') as destination: for chunk in file.chunks(): destination.write(chunk) return JsonResponse({'success': True, 'message': '文件夹上传成功'}) except Exception as e: return JsonResponse({'success': False, 'error': str(e)}) else: return JsonResponse({'success': False, 'error': '仅支持POST请求'})
3. 关键注意事项
- 权限问题:确保Django运行的用户对
STATIC_ROOT目录有写入权限,否则会保存失败。 - CSRF令牌:前端必须带上CSRF令牌,否则Django会拒绝请求,上面的
getCookie函数已经处理了这个问题。 - 文件大小限制:如果上传的文件夹很大,需要修改Django的
settings.py中的文件上传限制:# 单个文件最大大小(比如50MB) FILE_UPLOAD_MAX_MEMORY_SIZE = 52428800 # 整个请求最大大小(比如200MB) DATA_UPLOAD_MAX_MEMORY_SIZE = 209715200 - 浏览器兼容性:
webkitRelativePath属性在Chrome、Firefox、Edge等主流浏览器都支持,但旧版IE可能不兼容。
内容的提问来源于stack exchange,提问作者solopiu
相关产品推荐
相关产品推荐

