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

如何在Python/Tornado中按RFC 5987规范编码Content-Disposition文件名?

在Python/Tornado中实现Content-Disposition头的filename编码(基于RFC 5987)

嘿,我刚好研究过这个问题,给你分享下实用的解决方案吧!

先理清楚基础逻辑

  • 处理Content-Disposition头里的特殊字符(比如中文)文件名,RFC 5987定义了一套标准的编码规范,这是目前最可靠的解决方案
  • 主流浏览器早在2012年11月就已经全面支持这个编码方式,不用太担心兼容性问题

Python/Tornado里的具体实现

目前Tornado确实没有内置的工具函数来做这件事,不过我们可以自己实现RFC 5987的编码逻辑,然后配合self.set_header来设置响应头。

第一步:实现编码函数

我们可以用Python标准库的urllib.parse来完成编码,写一个简单的工具函数:

import urllib.parse

def encode_rfc5987_filename(filename):
    # 按照RFC 5987规范,用UTF-8编码文件名
    encoded = urllib.parse.quote(filename, encoding='utf-8')
    # 返回符合规范的filename*参数格式
    return f"filename*=UTF-8''{encoded}"

第二步:在Tornado请求处理器中使用

接下来在你的请求处理类里,调用这个函数生成响应头内容:

import tornado.web

class FileDownloadHandler(tornado.web.RequestHandler):
    def get(self):
        # 你的原始文件名,比如包含中文或特殊字符
        target_filename = "我的文档_2024.txt"
        
        # 构造符合RFC 5987的Content-Disposition头
        disposition_header = f"attachment; {encode_rfc5987_filename(target_filename)}"
        
        # 设置响应头
        self.set_header('Content-Disposition', disposition_header)
        
        # 这里添加返回文件内容的逻辑,比如读取本地文件并返回
        # with open(target_filename, 'rb') as f:
        #     self.write(f.read())
        self.set_header('Content-Type', 'application/octet-stream')

额外的兼容性小技巧

如果你的服务需要兼容非常老旧的浏览器(比如IE8及更早版本),可以同时设置传统的filename参数和标准的filename*参数,这样新旧浏览器都能正常识别:

disposition_header = f"attachment; filename=\"{target_filename}\"; {encode_rfc5987_filename(target_filename)}"

不过现在这种老旧浏览器的使用场景已经极少,大部分情况下只用filename*就足够了。

内容的提问来源于stack exchange,提问作者Francesco Marchetti-Stasi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:10:59