【问题标题】:How to serve static file with a hebrew name in python bottle?如何在 python 瓶中使用希伯来语名称提供静态文件?
【发布时间】:2013-11-14 13:30:37
【问题描述】:

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

@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)]

请帮忙。

请注意, 奥马尔。

【问题讨论】:

    标签: python unicode encoding bottle static-files


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      在最后一行尝试使用 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

      欲了解更多信息,请参阅Unicode In Python, Completely Demystified

      【讨论】:

      • 您能否详细说明如何以及与我正在使用的字符串编码有什么区别
      • 顺便说一下我用的是python 2.7
      • 这不起作用。没有异常但是没有找到文件,得到一个 HTTPError(404, "File does not exist.")
      【解决方案3】:

      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)  
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-07
        • 2020-11-30
        • 2012-11-09
        • 1970-01-01
        • 2010-10-04
        • 1970-01-01
        • 2012-10-05
        • 2018-12-24
        相关资源
        最近更新 更多