【问题标题】:Django: Unicode Filenames with ASCII headers?Django:带有 ASCII 标头的 Unicode 文件名?
【发布时间】:2011-02-13 12:09:35
【问题描述】:

我有一个奇怪编码的文件列表:02 - Charlie, Woody and You/Study #22.mp3,我认为这还不错,但 Django 或 nginx 似乎会遇到一些特殊字符。

>>> test = u'02 - Charlie, Woody and You/Study #22.mp3'
>>> test
u'02 - Charlie, Woody and You\uff0fStudy #22.mp3'

我使用 nginx 作为反向代理来连接到 django 的内置网络服务器(仍处于开发阶段)和我的数据库的 postgresql。我的数据库和表都是en_US.UTF-8,我正在使用 pgadmin3 在 django 之外查看我的表。我的问题有点超出我的标题,首先我应该如何在我的数据库中保存可能古怪的文件名?我目前的方法是

'path': smart_unicode(path.lstrip(MUSIC_PATH)),
'filename': smart_unicode(file)

当我打印出它们确实显示的值时 u'whateverthecrap'

我不确定我是否应该这样做,但假设现在我在尝试吐出下载时遇到问题。

我的下载视图如下所示:

def song_download(request, song_id):
    song = get_object_or_404(Song, pk=song_id)
    url = u'/static_music/%s/%s' % (song.path, song.filename)

    print url

    response = HttpResponse()
    response['X-Accel-Redirect'] = url
    response['Content-Type'] = 'audio/mpeg'
    response['Content-Disposition'] = "attachment; filename=test.mp3"

    return response

大多数文件都会下载,但是当我到达 02 - Charlie, Woody and You/Study #22.mp3 时,我会从 django 收到这个:'ascii' codec can't encode character u'\uff0f' in position 118: ordinal not in range(128), HTTP response headers must be in US-ASCII format

如果我的文件名超出范围,如何使用可接受的 ASCII 字符串? 02 - Charlie, Woody and You\uff0fStudy #22.mp3 似乎不起作用...

编辑 1

我的操作系统使用的是 Ubuntu。

【问题讨论】:

  • 我不清楚您的正斜杠字符/ 是这里的文件名的一部分还是父目录加文件名的一部分? (当然,由于与目录结构混淆,在大多数现代文件系统中,正斜杠字符“/”不允许作为文件名的一部分。)然而,要以 ASCII 安全的方式对正斜杠进行编码,你可以使用 '\u002f'... 但我不推荐它。
  • 这首歌更像是一个分隔符,我不知道他们是怎么弄进去的,但它不是一个真正的/,它是一个,这可能是它被允许的原因。这可能是一个糟糕的例子,但它已经在许多其他 unicode 字符上做到了。

标签: python django unicode nginx ascii


【解决方案1】:

虽然 是一个不寻常且不受欢迎的字符,但您的脚本会因任何非ASCII字符而中断。

response['X-Accel-Redirect'] = url

url 是 Unicode(它不是 URL,它是文件路径)。响应标头是字节。您需要对其进行编码。

response['X-Accel-Redirect'] = url.encode('utf-8')

假设您在使用 UTF-8 作为文件系统编码的服务器上运行。

(现在,如何对Content-Disposition 标头中的文件名进行编码......这是一个完全棘手的问题!)

【讨论】:

  • 哈哈抱歉,url 用作 url。我正在运行 Ubuntu 10.4 (Beta),有没有办法告诉我文件系统的编码?
  • 是的,除非您更改它,否则 Ubuntu 将是 UTF-8。除 Windows 之外的所有现代操作系统都使用 UTF-8。
  • 根据this answerfilename参数必须始终为ascii,例如:filename=test.encode('ascii', 'replace'),而较新的浏览器(在RFC-6266之后)可以使用filename*,例如:filename*=''urlquote(test)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-30
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-27
相关资源
最近更新 更多