Turbogears响应 - 发送utf-8文件名

时间:2014-11-23 15:39:32

标签: python-2.7 utf-8 response turbogears2

我正在使用Turbogears 2.3.3进行网络应用 在我的应用程序中,用户将获得一组指示,他们将需要相应地下载一些文件。
重要的是,他们能够以原始名称下载文件,这些文件将在utf8中。 这是我下载文件的方法:

import os
from webob.static import FileApp
from tg import expose, request, use_wsgi_app, response

....

@expose()
def download(self,**kw):
    response.headerlist.append(('Content-Disposition','attachment'))
    path_to_file = os.path.join(os.path.dirname(dfuswebapp.__file__), 'PrintFiles')
    file_with_path = os.path.join(path_to_file,kw['filename'])
    file = FileApp(file_with_path)
    return use_wsgi_app(file)

当我尝试获取这样的文件时,文件名为" download"扩展原始文件。

如果我尝试这段代码:

response.headerlist.append(('Content-Disposition','attachment;filename=%s'%str(kw['filename']))) 

如果kw [' filename']在utf-8中,我的大多数文件都会出现错误。 有没有办法有原始文件名?

谢谢你的帮助

1 个答案:

答案 0 :(得分:2)

可悲的是,你遇到了WSGI和HTTP中的许多黑暗角落之一。 正如WSGI规范所述:

  

另请注意,作为状态或作为状态传递给start_response()的字符串   响应头必须遵循RFC 2616的编码方式。那   是,它们必须是ISO-8859-1字符,或使用RFC 2047 MIME   编码

这意味着您的标题应该编码为latin-1或使用RFC2047,问题是由于浏览器的行为不可靠,因此对latin-1之外的标题的支持已被排除在外webob到目前为止(见https://github.com/Pylons/webob/issues/11#issuecomment-2819811)。

最佳解决方案可能是使用RFC6266手动编码Content-Disposition标头,filename*使用percentage encoding提供Content-Disposition: attachment; filename="EURO rates"; filename*=utf-8''%e2%82%ac%20rates 进行unicode编码。这将提供完全符合latin-1的结果,使WSGI满意,并且可以表示unicode UTF8字符。

这是一个简短的例子,给出了" EURO费率"和"€率"取决于浏览器:

{{1}}

有关此问题的讨论,请参阅StackOverflow上的这篇文章: How to encode the filename parameter of Content-Disposition header in HTTP?