Python requests对非ASCII文件名的问题

5

我正在使用Python的requests库发送一个请求。当附件参数中包含非ASCII字符时,会引发异常。而在只有ASCII数据存在的其他情况下,一切都正常。

您可以在此处查看异常信息

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'}

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

请展示错误跟踪。您提供的图片显示,有一些尝试使用意外字符创建标题的情况。但这可能是您代码中多个值的情况,堆栈跟踪将告诉我们更多信息。理想情况下,您应该提供一个可以运行并显示问题的简短代码片段。目前无法重现太多内容。 - Jan Vlcinsky
1个回答

3
当文件名包含非ASCII字符时,requests库会按照标准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) 

在调用requests时,需要明确指定文件名(假设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标准。


我已经在做这个了,问题是文件由于某些原因无法通过……没有异常(请参见编辑部分)。我将更新问题中的代码以避免混淆。 - omer bach
谢谢,我会与MailGun核实。如果是这种情况,我该如何强制请求按照MailGun的规定处理Unicode文件名呢? - omer bach
谢谢,我会等待Mailgun的回复。 - omer bach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接