You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django+AWS S3分片上传报错:无法获取文件路径导致上传失败

Django + boto3 分片上传到AWS S3 路径错误解决方法

错误原因

你遇到的FileNotFoundError是因为调用s3.upload_file()时传入的file_name_s3是客户端的文件名,但这个文件不存在于服务器本地——浏览器出于安全限制,不会把客户端文件的完整本地路径传给后端,且当前分片逻辑是把每个chunk写到服务器本地文件,而非直接传递完整文件到后端。


修复方案一:基于现有本地合并逻辑上传S3

你的代码已将分片合并到服务器的path = 'media/uploads/video_files/' + fileName_STR路径下,只需将这个本地路径传给s3.upload_file()即可:

修改views.py中的问题代码段:

# 原错误代码
s3.upload_file(file_name_s3 ,bucket,str(fileName_STR))

# 修改后的代码
# 先确保bucket变量已定义(比如从settings读取:bucket = settings.AWS_STORAGE_BUCKET_NAME)
# 建议用绝对路径避免问题,比如结合Django的MEDIA_ROOT
import os
from django.conf import settings

local_file_path = os.path.join(settings.MEDIA_ROOT, 'uploads/video_files/', fileName_STR)
s3.upload_file(local_file_path, bucket, f'uploads/video_files/{fileName_STR}')
  • local_file_path是合并后文件在服务器的绝对路径,避免相对路径引发的找不到文件问题
  • 第三个参数是S3上的对象键(即文件在S3中的存储路径/名称),可根据需求调整

修复方案二:直接用S3 Multipart Upload(更优)

若不想先将文件存在服务器本地,推荐使用boto3的分片上传API直接处理客户端传来的chunk,节省服务器存储空间且更高效:

步骤1:初始化Multipart Upload

当第一个chunk上传时(existingPath == 'null'),创建Multipart Upload并保存upload ID:

# 初始化Multipart Upload
response = s3.create_multipart_upload(
    Bucket=bucket,
    Key=f'uploads/video_files/{fileName_STR}'
)
upload_id = response['UploadId']
# 需在Post模型中新增upload_id字段,用于后续分片上传
FileFolder.upload_id = upload_id

步骤2:上传每个分片

每次收到chunk时,调用upload_part上传:

# 根据分片起始位置计算分片编号(S3要求编号从1开始)
part_number = int(nextSlice) // self.max_length + 1  # 需匹配你的分片大小逻辑
# 直接上传chunk内容到S3
response = s3.upload_part(
    Bucket=bucket,
    Key=f'uploads/video_files/{fileName_STR}',
    PartNumber=part_number,
    UploadId=upload_id,
    Body=file  # 即request.FILES['file'].read()获取的chunk内容
)
# 需在Post模型中新增字段存储分片ETag和编号,比如用JSONField存列表
FileFolder.parts.append({'PartNumber': part_number, 'ETag': response['ETag']})

步骤3:完成Multipart Upload

当最后一个chunk上传完成(end == 1),调用complete_multipart_upload:

# 整理分片信息格式
parts = [{'PartNumber': p['PartNumber'], 'ETag': p['ETag']} for p in FileFolder.parts]
# 完成分片上传
s3.complete_multipart_upload(
    Bucket=bucket,
    Key=f'uploads/video_files/{fileName_STR}',
    UploadId=upload_id,
    MultipartUpload={'Parts': parts}
)

额外注意事项

  • 浏览器无法获取客户端本地文件的完整路径,这是浏览器安全限制,后端永远无法拿到该路径,只能通过FormData接收文件内容
  • 若使用方案一,需确保服务器的media/uploads/video_files/目录有写入权限
  • 分片上传需处理异常,上传失败时要调用abort_multipart_upload清理S3上的未完成分片

内容的提问来源于stack exchange,提问作者MrLonely

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:29:51