我已经阅读了这里关于 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 版本是 0.3.4
.
我在 requests
中做了一些挖掘工作代码和请求似乎发送正常(即与文件一起),我在发送请求之前打印了请求,看到文件名确实编码为 RFC2231:
--6ea257530b254861b71626f10a801726
Content-Disposition: form-data; name="file0"; filename*=utf-8''%D7%90.txt
总而言之,我不完全确定问题是否出在 requests
内没有正确地将文件附加到请求或者如果 Flask
在拾取文件名根据 RFC2231 编码的文件时遇到问题。
更新: 在 requests
中遇到了这个问题GitHub: https://github.com/kennethreitz/requests/issues/2505
最佳答案
我认为这里的编码可能存在混淆 -
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')})
我有点惊讶它并没有在尝试打开文件的客户端上抛出错误 - 你在客户端看不到任何指示错误的信息?
编辑:确认或否定我的想法的一种简单方法当然是从客户端内部打印出内容以确保其被正确读取。
关于带有 unicode 文件名的 python-requests post,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33717690/