鉴于具有多个表示(媒体类型)的资源不使用自定义CherryPy“工具”来处理“Accept”HTTP标头的解释和响应实体主体的序列化,CherryPy会引发以下{{1在适当地设置“Content-Type”HTTP标头后从页面处理程序返回内容时出现异常,但仅适用于某些媒体类型:
ValueError:页面处理程序必须返回字节。如果你想返回unicode,请使用tools.encode。
示例:
ValueError
这适用于两种媒体类型,但JSON表示将被错误地声明为HTML(默认值)。
contentType = tools.accept.callable(media = ['application/json', 'text/html'])
if contentType == 'application/json':
return json.dumps(studies)
elif contentType == 'text/html':
...
在将JSON内容作为字符串返回时,会引发上述异常。
尝试确保contentType = tools.accept.callable(media = ['application/json', 'text/html'])
response.headers['Content-Type'] = "{mediaType}; charset=utf-8".format(mediaType = contentType)
if contentType == 'application/json':
return json.dumps(studies)
elif contentType == 'text/html':
...
确实已启用,并明确将tools.encode
设置为tools.encode.encoding
(即使它是默认值)失败。对于HTML表示来说,事情很有用,所以看起来它也适用于JSON表示。
目前utf-8
的文档似乎相当稀疏,因此最好的方法并不是很明显。
答案 0 :(得分:2)
只有当顶级媒体类型为text
(text/*
)时,CherryPy编码工具才会自动对内容进行编码。
有一种方法可以使用encode.text_only
设置来控制它,但它是全局的,因此在返回真正不应编码的内容时可能会引入问题。在撰写本文时,一个开放式问题会跟踪功能请求,以便更精细地控制此行为:#1123。
因此,在这种特殊情况下解决此问题的最合适方法是手动编码内容:
contentType = tools.accept.callable(media = ['application/json', 'text/html'])
response.headers['Content-Type'] = "{mediaType}; charset=utf-8".format(mediaType = contentType)
if contentType == 'application/json':
return json.dumps(studies).encode('utf-8')
elif contentType == 'text/html':
...