我有HTTP头的问题,他们在ASCII编码,我想提供一个下载文件的名称可以是非ASCII视图。
response['Content-Disposition'] = 'attachment; filename="%s"' % (vo.filename.encode("ASCII","replace"), )
字符串
我不想使用非ASCII文件名的静态文件来解决同样的问题,但在这种情况下,文件系统和文件名编码会有问题。(我不知道目标操作系统。)
我已经尝试过urllib.quote(),但它引发了KeyError异常。
也许我做错了什么,但也许这是不可能的。
7条答案
按热度按时间nkcskrwz1#
这是一个FAQ。
有些浏览器实现了专有的扩展(IE,Chrome),有些则实现了RFC 2231(Firefox,Opera)。
请参见http://greenbytes.de/tech/tc2231/上的测试用例。
更新:截至2012年11月,所有当前的桌面浏览器都支持RFC 6266和RFC 5987中定义的编码(Safari >= 6,IE >= 9,Chrome,Firefox,Opera,Konqueror)。
a64a0gku2#
不要在Content-Disposition中发送文件名。没有办法使非ASCII头参数跨浏览器工作()。
相反,只发送“Content-Disposition:attachment”,并将文件名作为URL编码的UTF-8字符串保留在URL的尾部(PATH_INFO),以便浏览器默认选择和使用。UTF-8 URL在浏览器中的处理比与Content-Disposition有关的任何事情都要可靠得多。
(:实际上,甚至没有一个当前的标准来说明它应该如何做,因为RFC 2616,2231和2047之间的关系非常不正常,Julian正试图在规范级别上清理这些东西。
oalqel3c3#
请注意,在2011年,RFC 6266(特别是附录D)对这个问题进行了权衡,并提出了具体建议。
也就是说,您可以发出一个只包含ASCII字符的
filename
,然后发出一个包含RFC 5987格式文件名的filename*
,以供那些理解它的代理使用。通常情况下,这看起来像
filename="my-resume.pdf"; filename*=UTF-8''My%20R%C3%A9sum%C3%A9.pdf
,其中Unicode文件名(“My Résumé.pdf”)被编码为UTF-8,然后被编码(注意,不要对空格使用+
)。请务必阅读RFC 6266和RFC 5987(或者使用一个健壮且经过测试的库来为您抽象这些内容),因为我在这里的总结缺乏重要的细节。
kx1ctssn4#
从Django 2.1开始(参见issue #16470),您可以使用
FileResponse
,它将正确设置附件的Content-Disposition
头。从Django 3.0开始(issue #30196),它也将正确设置inline
文件。例如,要将MIME类型为
image/jpeg
的名为my_img.jpg
的文件作为HTTP响应返回:字符串
或者,如果你不能使用
FileResponse
,你可以使用FileResponse
源代码中的相关部分来自己设置Content-Disposition
头。下面是该源代码的当前外观:型
1szpjjfi5#
我可以说我已经成功地使用了新的(RFC 5987)格式来指定一个用电子邮件表单(RFC 2231)编码的头。我提出了以下解决方案,它基于django-sendfile项目的代码。
字符串
我只在Python 3.4和Django 1.8上测试过我的代码。所以django-sendfile中类似的解决方案可能更适合你。
在Django的跟踪器中有一个long standing ticket,它承认这一点,但还没有提出任何补丁。所以不幸的是,这是我能找到的最接近使用一个健壮的测试库,如果有更好的解决方案,请让我知道。
eivgtgni6#
Django的
escape_uri_path
函数是对我有效的解决方案。在这里阅读Django文档,查看当前指定的RFC标准。
字符串
z4iuyo4d7#
黑客:
字符串