Python Requests报'Remote end closed connection without response'问题求助
问题描述
在VirtualBox的Ubuntu 22.04.2 LTS(Windows 10主机)上编写脚本,需通过POST请求上传JSON文件和传感器名称字符串至指定接口,使用requests库时出现错误:Remote end closed connection without response。但通过curl发送请求、Python发送GET请求均正常,尝试添加User-Agent请求头也未解决问题。
相关代码
headers = { 'accept': '*/*', 'Content-Type': 'multipart/form-data', } files = { 'data': (None, './dati_1.json'), 'sensor_name': (None, 'SENSOR_NAME'), } response = requests.post('http://IP_ADDRESS/sensors/store', headers=headers, files=files) print(response)
报错信息
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 699, in urlopen httplib_response = self._make_request( File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 445, in _make_request six.raise_from(e, None) File "<string>", line 3, in raise_from File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 440, in _make_request httplib_response = conn.getresponse() File "/usr/lib/python3.10/http/client.py", line 1374, in getresponse response.begin() File "/usr/lib/python3.10/http/client.py", line 318, in begin version, status, reason = self._read_status() File "/usr/lib/python3.10/http/client.py", line 287, in _read_status raise RemoteDisconnected("Remote end closed connection without" http.client.RemoteDisconnected: Remote end closed connection without response During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send resp = conn.urlopen( File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 755, in urlopen retries = retries.increment( File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 532, in increment raise six.reraise(type(error), error, _stacktrace) File "/usr/lib/python3/dist-packages/six.py", line 718, in reraise raise value.with_traceback(tb) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 699, in urlopen httplib_response = self._make_request( File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 445, in _make_request six.raise_from(e, None) File "<string>", line 3, in raise_from File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 440, in _make_request httplib_response = conn.getresponse() File "/usr/lib/python3.10/http/client.py", line 1374, in getresponse response.begin() File "/usr/lib/python3.10/http/client.py", line 318, in begin version, status, reason = self._read_status() File "/usr/lib/python3.10/http/client.py", line 287, in _read_status raise RemoteDisconnected("Remote end closed connection without" urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/azzurra/tesi/prova1.py", line 39, in <module> response = requests.post('http://131.114.51.60:3100/sensors/store', headers=headers, files=files) File "/usr/lib/python3/dist-packages/requests/api.py", line 119, in post return request('post', url, data=data, json=json, **kwargs) File "/usr/lib/python3/dist-packages/requests/api.py", line 61, in request return session.request(method=method, url=url, **kwargs) File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request resp = self.send(prep, **send_kwargs) File "/usr/lib/python3/dist-packages/requests/sessions.py", line 655, in send r = adapter.send(request, **kwargs) File "/usr/lib/python3/dist-packages/requests/adapters.py", line 498, in send raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
解决方案
问题出在两个地方:
- 手动指定了
Content-Type: multipart/form-data请求头,但requests处理files参数时会自动生成包含boundary分隔符的正确multipart请求头,手动指定会覆盖这个自动生成的头,导致服务端无法解析请求,直接断开连接。 - 你没有实际读取JSON文件内容,只是传递了文件名字符串,服务端无法获取到文件数据。
修改后的代码:
import requests headers = { 'accept': '*/*', # 移除手动设置的Content-Type,让requests自动生成 } # 读取JSON文件的二进制内容 with open('./dati_1.json', 'rb') as json_file: file_content = json_file.read() files = { # 指定文件名、文件内容和正确的MIME类型 'data': ('dati_1.json', file_content, 'application/json'), 'sensor_name': (None, 'SENSOR_NAME'), } response = requests.post('http://IP_ADDRESS/sensors/store', headers=headers, files=files) print(response.status_code) print(response.text)
额外优化建议:
- 如果传感器名称只是普通表单字段,可单独用
data参数传递,无需放到files里:
data = {'sensor_name': 'SENSOR_NAME'} files = {'data': ('dati_1.json', file_content, 'application/json')} response = requests.post('http://IP_ADDRESS/sensors/store', headers=headers, data=data, files=files)
- 开启调试日志对比请求差异:
import logging import http.client http.client.HTTPConnection.debuglevel = 1 logging.basicConfig() logging.getLogger().setLevel(logging.DEBUG) requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.DEBUG) requests_log.propagate = True
内容的提问来源于stack exchange,提问作者Kaz
相关产品推荐
相关产品推荐

