CherryPy Web服务接收text/plain类型POST请求报错的解决求助
问题分析与解决方案
你遇到的400错误本质是请求体不是合法JSON格式:即使你让json_in接受text/plain类型,CherryPy依然会尝试把请求体解析成JSON,但你的请求内容不符合JSON规范,导致解析失败。
看你的客户端代码:
headers = {'Content-Type': 'text/plain'} response = requests.post('http://localhost:8080/process', headers=headers, data={})
当requests的data参数传入空字典时,它会自动把请求体编码成application/x-www-form-urlencoded格式的内容(类似空字符串或=),这显然不是合法的JSON,所以CherryPy返回400错误。
解决方法
方法1:调整客户端请求,发送合法JSON内容(推荐)
如果只是想让服务接受text/plain类型的JSON请求,修改客户端代码,确保data传入合法JSON字符串:
import requests import json headers = {'Content-Type': 'text/plain'} # 将空字典转为标准JSON字符串 response = requests.post('http://localhost:8080/process', headers=headers, data=json.dumps({}))
服务端保持你修改后的@cherrypy.tools.json_in(content_type=['application/json', 'text/plain'])即可正常响应。
方法2:服务端兼容非JSON格式的text/plain请求(若业务需要)
如果业务场景确实需要接受非JSON的text/plain内容,不要依赖json_in工具,改为手动读取并处理请求体:
import cherrypy class MyWebService(object): @cherrypy.expose @cherrypy.tools.json_out() def process(self): # 手动读取请求体 content_type = cherrypy.request.headers.get('Content-Type', '') request_body = cherrypy.request.body.read().decode('utf-8') # 根据Content-Type做差异化处理 if content_type in ['application/json', 'text/plain']: try: # 尝试解析JSON,失败则使用原始文本 input_data = cherrypy.request.json except ValueError: input_data = request_body else: raise cherrypy.HTTPError(415, "Unsupported Media Type") return "hello world!" if __name__ == '__main__': config = {'server.socket_host': '0.0.0.0'} cherrypy.config.update(config) cherrypy.quickstart(MyWebService())
这样不管是发送JSON格式的text/plain还是普通文本,服务都能正常处理。
补充说明
json_in工具的核心作用是自动将请求体解析为JSON对象,所以只要使用它,就要求请求体必须是合法JSON,和Content-Type无关。你之前添加text/plain只是允许该类型的请求进入,但内容不符合JSON规范依然会报错。requests的json参数会自动把字典转为JSON字符串,并自动设置Content-Type: application/json;而data参数默认采用表单编码,除非手动传入JSON字符串。
内容的提问来源于stack exchange,提问作者TripleH
相关产品推荐
相关产品推荐

