简体   繁体   English

带有 unicode 文件名的 python-requests 帖子

[英]python-requests post with unicode filenames

I've read through several related questions here on SO but didn't manage to find a working solution.我已经阅读了关于 SO 的几个相关问题,但没有找到可行的解决方案。

I have a Flask server with this simplified code:我有一个带有这个简化代码的 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)

Then in the client:然后在客户端:

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

When sending the first request with the non-utf-8 filename the server receives the request with the file and prints ImmutableMultiDict([('file0', <FileStorage: u'a.txt' (None)>)]) , but when sending the file with the utf-8 filename the server doesn't seem to receive the file as it prints ImmutableMultiDict([]) .当发送带有非 utf-8 文件名的第一个请求时,服务器接收带有文件的请求并打印ImmutableMultiDict([('file0', <FileStorage: u'a.txt' (None)>)]) ,但是当使用 utf-8 文件名发送文件,服务器似乎没有收到文件,因为它打印ImmutableMultiDict([])

I'm using requests 2.3.0 but the problem doesn't resolve with the latest version as well ( 2.8.1 ), Flask version is 0.10.1 and Flask-RESTful version is 0.3.4 .我正在使用 requests 2.3.0但问题也没有用最新版本( 2.8.1 )解决,Flask 版本是0.10.1而 Flask-RESTful 版本是0.3.4

I've done some digging in requests code and the request seems to be sent ok (ie with the file), and I printed the request right before it is being sent and see the file name was indeed encoded to RFC2231:我对requests代码进行了一些挖掘, requests似乎可以正常发送(即使用文件),我在发送请求之前打印了请求,并看到文件名确实被编码为 RFC2231:

--6ea257530b254861b71626f10a801726
Content-Disposition: form-data; name="file0"; filename*=utf-8''%D7%90.txt

To sum things up, I'm not entirely sure if the problem lies within requests that doesn't properly attach the file to the request or if Flask is having issues with picking up files with file names that are encoded according to RFC2231.综上所述东西,我不能完全肯定,如果问题在于内requests不正确的文件附加到该请求,或者如果Flask是具有拿起与根据RFC2231编码文件名的文件的问题。

UPDATE: Came across this issue in requests GitHub: https://github.com/kennethreitz/requests/issues/2505更新:requests GitHub 中遇到此问题: https : //github.com/kennethreitz/requests/issues/2505

I think maybe there's confusion here on encoding here -我认为这里的编码可能存在混淆 -

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

To send the second one to the server what you want to do is this:要将第二个发送到服务器,您要做的是:

requests.post('http://localhost:5000/', files={'file0': open(heb_file_name.encode('utf-8'), 'rb')})

I'm a little surprised that it doesn't throw an error on the client trying to open the file though - you see nothing on the client end indicating an error?我有点惊讶它没有在尝试打开文件的客户端上抛出错误 - 您在客户端上看不到任何指示错误的内容?

EDIT: An easy way to confirm or deny my idea is of course to print out the contents from inside the client to ensure it's being read properly.编辑:确认或否认我的想法的一种简单方法当然是从客户端内部打印出内容以确保它被正确读取。

I workaround this issue by manually reading the file with read() and then posting its contents:我通过使用read()手动读取文件然后发布其内容来解决此问题:

requests.post(upload_url, files={
    'file': ("photo.jpg", open(path_with_unicode_filename, 'rb').read())
})

Try this workaround: filename.encode("utf-8").decode("iso-8859-1") .试试这个解决方法: filename.encode("utf-8").decode("iso-8859-1")

Example:例子:

requests.post("https://example.com", files={"file":
    ("中文filename.txt".encode("utf-8").decode("iso-8859-1"), fobj, mimetype)})

I post this because this is my first result when searching python requests post filename encoding .我发布这个是因为这是我在搜索python requests post filename encoding时的第一个结果。

There are lots of RFC standards about Content-Disposition encoding.有很多关于Content-Disposition编码的 RFC 标准。 And it seems that different programs implement this part differently.似乎不同的程序对这部分的实现方式不同。

See stackoverflow: lots of RFCs and application tests , RFC 2231 - 4 , email.utils.encode_rfc2231 .请参阅stackoverflow:许多 RFC 和应用程序测试RFC 2231-4email.utils.encode_rfc2231

Java version answer here . Java 版本在这里回答

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM