我已经在SO上阅读了几个相关的问题,但没有找到可行的解决方案。
我有一个带有这个简化代码的Flask服务器:
app = Flask(__name__)
api = Api(app)
class SendMailAPI(Resource):
def post(self):
print request.files
return Response(status=200)
api.add_resource(SendMailAPI, '/')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
然后在客户端:
# coding:utf-8
import requests
eng_file_name = 'a.txt'
heb_file_name = u'א.txt'
requests.post('http://localhost:5000/', files={'file0': open(eng_file_name, 'rb')})
requests.post('http://localhost:5000/', files={'file0': open(heb_file_name, 'rb')})
当发送带有非utf-8文件名的第一个请求时,服务器接收带有该文件的请求并打印ImmutableMultiDict([('file0', <FileStorage: u'a.txt' (None)>)])
,但是当发送带有utf-8文件名的文件时,服务器似乎没有在打印ImmutableMultiDict([])
时收到该文件。
我正在使用请求2.3.0
,但问题也无法解决最新版本(2.8.1
),Flask版本为0.10.1
,Flask-RESTful版本为{{ 1}}。
我已经在0.3.4
代码中进行了一些挖掘,并且请求似乎已发送正常(即使用该文件),并且我在请求发送之前打印了请求,并且看到文件名确实已编码到RFC2231:
requests
总而言之,我不完全确定问题是否在--6ea257530b254861b71626f10a801726
Content-Disposition: form-data; name="file0"; filename*=utf-8''%D7%90.txt
范围内,是否未将文件正确附加到请求,或者requests
是否存在提取文件的问题根据RFC2231编码的文件名。
更新:在Flask
GitHub中遇到此问题:https://github.com/kennethreitz/requests/issues/2505
答案 0 :(得分:2)
我想这里的编码可能存在混淆 -
eng_file_name = 'a.txt' # ASCII encoded, by default in Python 2
heb_file_name = u'א.txt' # NOT UTF-8 Encoded - just a unicode object
要将第二个发送到服务器,您要执行的操作是:
requests.post('http://localhost:5000/', files={'file0': open(heb_file_name.encode('utf-8'), 'rb')})
我有点惊讶它虽然没有在试图打开文件的客户端上抛出错误 - 你在客户端看到什么都没有显示错误?
编辑:确认或否认我的想法的一个简单方法当然是从客户端内部打印出内容,以确保正确阅读。
答案 1 :(得分:1)
我通过手动阅读read()
文件然后发布其内容来解决此问题:
requests.post(upload_url, files={
'file': ("photo.jpg", open(path_with_unicode_filename, 'rb').read())
})
答案 2 :(得分:0)
尝试以下解决方法:
filename.encode("utf-8").decode("iso-8859-1")
。
示例:
requests.post("https://example.com", files={"file":
("中文filename.txt".encode("utf-8").decode("iso-8859-1"), fobj, mimetype)})
我发布此信息是因为这是我搜索python requests post filename encoding
时的第一个结果。
关于Content-Disposition
编码,有很多RFC标准。
似乎不同的程序对这部分的实现方式有所不同。
请参见stackoverflow: lots of RFCs and application tests,RFC 2231 - 4,email.utils.encode_rfc2231。