Django基于UUID的下载功能返回错误文件名问题
解决Django下载时用真实文件名替代UUID的问题
嘿,这个场景我太熟悉了!用UUID做索引确实能避开不少路径安全问题,但浏览器默认会把URL末尾的UUID当文件名,确实有点闹心。咱们只需要在返回下载响应的时候,给浏览器明确指定真实文件名就行,具体操作看下面:
核心思路
通过设置HTTP响应头里的Content-Disposition,告诉浏览器「这个文件要下载,并且保存的时候用这个名字」,替代默认用URL里UUID的行为。
具体代码修改
假设你的下载模型(比如叫Download)里有存储真实文件名的字段(比如original_filename),同时文件存在服务器的某个路径下,那可以把你的视图函数改成这样:
from django.http import FileResponse from django.shortcuts import get_object_or_404 from urllib.parse import quote # 处理含特殊字符的文件名 def new_download(request, d_uuid=None): # 通过UUID获取对应的下载记录 download = get_object_or_404(YourDownloadModel, uuid=d_uuid) # 打开要下载的文件(如果是从云存储取文件,这里逻辑需要对应调整) file_handle = open(download.file.path, 'rb') # 用FileResponse处理大文件更高效(流式传输,不占用服务器过多内存) response = FileResponse(file_handle) # 对特殊字符文件名编码,避免浏览器显示乱码 encoded_filename = quote(download.original_filename) # 设置Content-Disposition头,指定下载文件名 # 这种写法兼容大部分现代浏览器,支持UTF-8编码的文件名 response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}' return response
关键细节解释
attachment:告诉浏览器这是需要下载的附件,而非直接在浏览器内打开的内容filename*=UTF-8''{encoded_filename}:遵循RFC 5987标准的写法,能正确处理中文、空格这类非ASCII字符的文件名,彻底避免乱码问题FileResponse:相比普通HttpResponse,它会分段读取文件,适合大文件下载场景,不会把整个文件加载到服务器内存里
这样修改后,用户点击下载链接时,浏览器就会用你指定的真实文件名保存文件,再也不会出现UUID命名的情况啦!
内容的提问来源于stack exchange,提问作者Benjamin Schollnick
相关产品推荐
相关产品推荐

