我正在使用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中,我的大多数文件都会出现错误。
有没有办法有原始文件名?
谢谢你的帮助
答案 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?