【问题标题】:python requests issues with non ascii file namespython请求非ascii文件名的问题
【发布时间】:2014-08-15 08:27:20
【问题描述】:

我正在使用 python 请求来发布请求。 当附件参数有一些非 ascii 字符时会引发异常,在其他只存在 ascii 数据的情况下,一切都很好。

you can see the exception here

response = requests.post(url="https://api.mailgun.net/v2/%s/messages" % utils.config.mailDomain,
                auth=("api", utils.config.mailApiKey),
                data={
                        "from" : me,
                        "to" : recepients,
                        "subject" : subject,
                        "html" if html else "text" : message
                    },

                files= [('attachment', codecs.open(f.decode('utf8'))) for f in attachments] if attachments and len(attachments) else []                                
                )

编辑: 使用 utf8 解码文件名后,我没有收到异常,但是文件未附加。 我通过附加一个名称中只有 ascii 字符的文件来调试请求,请求标头请求构建是:

{'Content-Type': None, 'Content-Location': None, 'Content-Disposition': u'form-data; name="attachment"; filename="Hello.docx"'}

成功了,我正在收到带有附件的邮件。

但是,当使用带有希伯来字符的文件时,请求的标头是:

{'Content-Type': None, 'Content-Location': None, 'Content-Disposition': 'form-data; name="attachment"; filename*=utf-8\'\'%D7%91%D7%93%D7%99%D7%A7%D7%94.doc'}

我收到了邮件,但没有附加文件。有什么想法吗?

【问题讨论】:

  • 向我们展示错误跟踪。您提供的图片显示,有人尝试使用意外字符创建标题。但这可能是您的代码中有多个值的情况,stacktrace 会告诉我们更多信息。理想情况下,您应该提供一小段代码,它可以运行并显示问题。目前无法复制太多。

标签: python encoding decode python-requests mailgun


【解决方案1】:

当文件名包含非 ascii 时,请求库会按照标准 RFC 2231 对其进行编码。格式如您所见:filename*=utf-8''......。似乎 MailGun 不支持这个标准,结果,非 ascii 文件名丢失了。您可以联系 MailGun 以确认他们期望的 unicode 文件名格式。

作为一种不完美的解决方法,您可以将非 ascii 字符替换为:

def replace_non_ascii(x): return ''.join(i if ord(i) < 128 else '_' for i in x) 

并在调用请求时明确指定文件名(假设 attachments 是基于 unicode 的文件名列表):

files= [('attachment', (replace_non_ascii(f), codecs.open(f))) for f in attachments] ...

编辑

如果您想自定义标头格式,我们假设(而不是标准 RFC 2231)MailGun 可以接受这种格式:

filename="%D7%91%D7%93%D7%99%D7%A7%D7%94.doc"

然后您可以将文件名自定义为:

import urllib
def custom_filename(x): return urllib.quote(x.encode('utf8'))

files= [('attachment', (custom_filename(f), codecs.open(f))) for f in attachments] ...

根据 MailGun 的响应,您可能需要调整 requests 的代码或改用低级库 (urllib2)。希望他们可以支持 RFC 2231

【讨论】:

  • 我已经在这样做了,问题是文件由于某种原因没有通过......没有例外(参见编辑部分)。我将更新问题中的代码以避免混淆
  • 谢谢,我会用 mailGun 检查。如果是这种情况,我如何强制请求以 mailGun 状态的方式处理 unicode 文件名?
  • 谢谢,等待mailgun的回复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-19
  • 2014-06-20
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多