更改Content-Type后,返回的内容不会自动编码

时间:2016-12-30 11:02:18

标签: cherrypy

鉴于具有多个表示(媒体类型)的资源不使用自定义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的文档似乎相当稀疏​​,因此最好的方法并不是很明显。

1 个答案:

答案 0 :(得分:2)

只有当顶级媒体类型为texttext/*)时,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':
    ...