我使用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'}
我收到邮件但没有附加文件。有什么想法吗?
答案 0 :(得分:3)
当文件名包含非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)
在调用请求时显式指定filename(假设attachments
是基于unicode的文件名列表):
files= [('attachment', (replace_non_ascii(f), codecs.open(f))) for f in attachments] ...
<强> EDITS 强>
如果你想自定义标题格式,我们假设(而不是标准的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