3

我收到来自客户端的请求,要求从服务器下载一些文件。文件名是希伯来语。

@bottle.get("/download/<folder_name>/<file_name>")
def download(folder_name, file_name):

    file_name =  file_name.decode('utf-8')
    folder_name =  folder_name.decode('utf-8')

    if os.path.exists(os.path.join(folder_name, file_name)):
        return bottle.static_file(file_name, root=folder_name, download=True)

最后一行失败:

return bottle.static_file(file_name, root=folder_name, download=True)

我得到一个例外:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 22-25: ordinal not in range(128)

我不知道我在这里做错了什么。

Callstack 显示异常源自 python 瓶代码:

File "C:\Python27\Lib\site-packages\bottle-0.10.9-py2.7.egg\bottle.py", line 1669, in __setitem__
  def __setitem__(self, key, value): self.dict[_hkey(key)] = [str(value)]

请帮忙。

请注意,奥马尔。

4

3 回答 3

3

Bottle 正在尝试将Content-DispositionHTTP 响应的标头设置为attachment; filename=.... 这不适用于非 ASCII 字符,因为 Bottle 在str内部处理 HTTP 标头......但即使没有,也没有跨浏览器兼容的方式来设置 aContent-Disposition与非 ASCII filename。(背景。)

您可以设置download='...'为安全的纯 ASCII 字符串来覆盖 Bottle 的默认猜测(使用本地文件名,包含 Unicode)。

或者,省略download参数并依靠浏览器从 URL 的末尾猜测文件名。(这是获取 Unicode 下载文件名的唯一广泛兼容的方法。)不幸的是,Bottle 将Content-Disposition完全省略,因此请考虑将返回的响应中的标头更改为包含Content-Disposition: attachment没有文件名的纯文本。或者也许你不在乎,如果Content-Type它总是会被下载。

于 2013-11-14T15:52:02.280 回答
0

send_file 参数必须是 unicode。这是瓶 0.5.8 的解决方案:

# -*- coding: utf-8 -*-
from bottle import route, run, request, send_file, WSGIRefServer
@route('/:filename#.*#')
def static_file(filename):
    send_file(filename.decode('utf-8'), root=ur'g:\Folder')
run(server=WSGIRefServer, host='192.168.1.5', port=80)  
于 2015-03-05T21:57:01.437 回答
0

在最后一行尝试使用utf-8编解码器将 unicode 字符串编码为二进制:

return bottle.static_file(file_name.encode("utf-8"), root=folder_name.encode("utf-8"), download=True)

从您提供的代码来看,该方法似乎bottle.static_file需要一个二进制格式的字符串,ascii因此执行了使用编解码器的默认转换(从错误消息中可以看出)。在您的字符串中,您使用不属于 ascii 的希伯来字符,默认转换失败。您需要使用支持国家字母的编解码器,例如utf-8.

有关更多信息,请参阅Python 中的 Unicode,完全揭秘

于 2013-11-14T14:26:27.563 回答