【问题标题】:Returned content not encoded automatically after changing Content-Type更改 Content-Type 后返回的内容未自动编码
【发布时间】:2016-12-30 11:02:18
【问题描述】:

鉴于具有多种表示(媒体类型)的资源不使用自定义 CherryPy“工具”来处理“接受”HTTP 标头的解释和响应实体主体的序列化,CherryPy 引发以下ValueError在适当设置“Content-Type”HTTP 标头后从页面处理程序返回内容时出现异常,但仅适用于某些媒体类型:

ValueError:页面处理程序必须返回字节。如果您希望返回 unicode,请使用 tools.encode。

例子:

contentType = tools.accept.callable(media = ['application/json', 'text/html'])

if contentType == 'application/json':
    return json.dumps(studies)
elif contentType == 'text/html':
    ...

这适用于两种媒体类型,尽管 JSON 表示会被错误地声明为 HTML(默认)。

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':
    ...

这里将 JSON 内容作为字符串返回时会引发上述异常。

尝试确保确实启用了tools.encode 并将tools.encode.encoding 显式设置为utf-8(即使它是默认值)失败。事情适用于 HTML 表示,所以它似乎也适用于 JSON 表示。

目前tools.encode 的文档似乎相当稀少,因此最好的方法不是很明显。

【问题讨论】:

    标签: cherrypy


    【解决方案1】:

    CherryPy 编码工具仅在顶级媒体类型为text (text/*) 时自动对内容进行编码。

    有一种方法可以通过 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':
        ...
    

    【讨论】:

    • 请将此标记为正确答案。附言随意提出一个拉取请求:)
    • @webKnjaZ 谢谢,通过确认我感觉更好。一个最有用的 PR 可能只是一个文档修复,但我担心我的贡献不会超出这个问答(如果其他人对这个特定场景感到惊讶,我希望可以很容易地找到它)。无论如何现在;-)。
    • 无论如何,我已经从那个问题中引用了这里
    猜你喜欢
    • 2017-07-10
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 2019-07-20
    相关资源
    最近更新 更多