Flask文件下载send_file中文文件名处理解决方案

发布于:2025-07-03 ⋅ 阅读:(17) ⋅ 点赞:(0)

Flask文件下载中文文件名处理解决方案

问题背景

在Web应用开发中,当用户下载包含中文字符的文件时,经常会遇到文件名乱码或无法正确显示的问题。这是由于HTTP协议中的 Content-Disposition 头部字段对非ASCII字符的处理限制导致的。

问题分析

核心问题

  • 编码问题 :HTTP头部字段默认使用ASCII编码,无法直接支持中文等Unicode字符
  • 浏览器兼容性 :不同浏览器对非ASCII文件名的处理方式不同
  • RFC标准 :需要遵循RFC 6266标准来正确处理国际化文件名

常见症状

  • 下载的文件名显示为乱码
  • 中文文件名变成问号或其他符号
  • 部分浏览器无法正确解析文件名

解决方案

技术实现

在Flask应用中,我们采用了双重编码策略来确保中文文件名的正确处理:

from urllib.parse import quote
from flask import send_file

# 设置文件名,支持中文文件名
file_name = quote(download_name)
response.headers['Content-Disposition'] = f'attachment; filename="{file_name}"; filename*=utf-8\'\'\'{file_name}'

关键技术点

  1. URL编码处理
file_name = quote(download_name)
  • 使用 urllib.parse.quote() 对文件名进行URL编码
  • 将中文字符转换为百分号编码格式(如: %E4%B8%AD%E6%96%87 )
  1. 双重文件名策略
response.headers['Content-Disposition'] = f'attachment; filename="{file_name}"; 
filename*=utf-8\'\'\'{file_name}'

参数说明:

  • filename=“{file_name}” :为旧版浏览器提供ASCII兼容的文件名
  • filename*=utf-8’‘’{file_name} :符合RFC 6266标准的国际化文件名 3. RFC 6266标准格式
filename*=charset'language'encoded-filename
  • charset :字符集(utf-8)
  • language :语言标识(空字符串表示未指定)
  • encoded-filename :URL编码后的文件名

完整实现示例

class TaskDownloadAPI(Resource):
    def get(self, task_id):
        """下载翻译后的文件"""
        try:
            # ... 其他业务逻辑 ...
            
            # 获取原始文件名
            download_name = task_info.get('original_filename')
            if not download_name:
                file_ext = os.path.splitext(output_file)[1]
                download_name = f"translated_{task_id}{file_ext}"
            
            # 创建响应
            response = send_file(
                output_file,
                as_attachment=True
            )
            
            # 设置文件名,支持中文文件名
            file_name = quote(download_name)
            response.headers['Content-Disposition'] = f'attachment; filename="{file_name}"; filename*=utf-8\'\'\'{file_name}'
            
            return response
            
        except Exception as e:
            logger.error(f"文件下载异常 - 任务ID: {task_id}, 错误: {str(e)}")
            return {'error': f'下载文件时发生错误: {str(e)}'}, 500

网站公告

今日签到

点亮在社区的每一天
去签到