如何在同一Chalice应用的不同路由分别返回图片与JSON?
解决Chalice中二进制响应与JSON响应共存的问题
这个问题的核心是全局设置binary_types=['*/*']后,Chalice会将所有响应视为二进制数据,要求响应体必须是bytes类型,但你的/echo路由返回的是JSON字符串(默认序列化后的结果),导致类型不匹配报错。同时,如果去掉这个全局设置,图片路由又会因为Chalice无法识别二进制响应而出现Accept头相关的问题。
下面提供两种可行的解决方案:
方案一:精准配置Binary Types(推荐)
不要用*/*全局匹配所有类型,只指定需要二进制处理的媒体类型(比如你的图片接口用到的image/jpeg),这样JSON响应会被Chalice正常处理,图片响应也能正确识别:
from chalice import Chalice, Response from urllib.request import Request, urlopen from urllib.parse import unquote import io app = Chalice(app_name='photo') # 只设置图片相关的二进制类型,而非全局匹配 app.api.binary_types = ['image/jpeg'] # 如果需要支持其他图片格式,可以添加进来,比如image/png @app.route('/get-photo/{url}/{maxWidth}/{maxHeight}', methods=['GET']) def getPhoto(url, maxWidth, maxHeight): return Response( load(unquote(url), int(maxWidth), int(maxHeight)), headers={ 'Content-Type': 'image/jpeg' }, status_code=200) def load(url, maxWidth, maxHeight): print(url) req = Request(url) req.add_header('accept', 'image/jpeg') image = urlopen(req).read() return thumbnail(image, maxWidth, maxHeight) from PIL import Image def thumbnail(image, maxWidth, maxHeight): im = Image.open(io.BytesIO(image)) im.thumbnail((maxWidth,maxHeight), Image.ANTIALIAS) with io.BytesIO() as output: im.save(output, format="JPEG") return output.getvalue() @app.route('/echo', methods=['POST']) def preload(): # 现在无需额外处理,Chalice会正常序列化JSON响应 return Response(app.current_request.json_body, status_code=200)
这种方式最符合Chalice的设计逻辑,避免不必要的全局二进制处理。
方案二:将JSON响应转为Bytes类型(兼容全局*/*场景)
如果因为某些原因必须保留binary_types=['*/*'],你可以手动将JSON响应序列化为bytes类型,满足Chalice对二进制响应的要求:
from chalice import Chalice, Response from urllib.request import Request, urlopen from urllib.parse import unquote import io import json # 导入json模块 app = Chalice(app_name='photo') app.api.binary_types =['*/*'] @app.route('/get-photo/{url}/{maxWidth}/{maxHeight}', methods=['GET']) def getPhoto(url, maxWidth, maxHeight): return Response( load(unquote(url), int(maxWidth), int(maxHeight)), headers={ 'Content-Type': 'image/jpeg' }, status_code=200) def load(url, maxWidth, maxHeight): print(url) req = Request(url) req.add_header('accept', 'image/jpeg') image = urlopen(req).read() return thumbnail(image, maxWidth, maxHeight) from PIL import Image def thumbnail(image, maxWidth, maxHeight): im = Image.open(io.BytesIO(image)) im.thumbnail((maxWidth,maxHeight), Image.ANTIALIAS) with io.BytesIO() as output: im.save(output, format="JPEG") return output.getvalue() @app.route('/echo', methods=['POST']) def preload(): json_body = app.current_request.json_body # 将JSON字典序列化为字符串,再转为bytes response_body = json.dumps(json_body).encode('utf-8') return Response( response_body, headers={'Content-Type': 'application/json'}, status_code=200 )
这样修改后,/echo的响应体是bytes类型,符合Chalice的二进制处理要求,同时/get-photo也能正常工作。
内容的提问来源于stack exchange,提问作者Alex R
相关产品推荐
相关产品推荐

