如何确定客户端是否需要JSON响应

时间:2015-07-20 15:02:55

标签: python http http-headers mime-types

在我的Werkzeug应用程序中,如果客户端需要JSON或返回404或500的常用HTML页面,我会拦截所有错误响应并尝试使用JSON响应进行响应:

def handle_error_response(self, environ, start_response, exc):
    if ('application/json' in environ.get('CONTENT_TYPE', '')
            and exc.get_response().content_type != 'application/json'):
        start_response('%s %s' % (exc.code, exc.name),
                       (('Content-Type', 'application/json'), ))
        return (json.dumps({"success": False, "error": exc.description}, ensure_ascii=False), )
    # go the regular path
    ...

在此解决方案中,我依赖于包含字符串Content-Type的{​​{1}}标头。

然而,这并不是一个正确的解决方案,因为维基百科说:

  

Content-Type 请求正文的MIME类型(与POST和PUT请求一起使用)

检查'application/json'是否在标头'text/html'内是否是一个好的策略,然后返回HTML响应,否则返回JSON响应?

还有其他更强大的解决方案吗?

Chrome请求HTML网页标题时

Accept
当Ember发出API请求时发送

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
发送

也许应该考虑Accept: application/json, text/javascript, */*; q=0.01

2 个答案:

答案 0 :(得分:0)

您应该将AcceptMixin添加到您的请求对象中。

执行此操作后,您可以在请求对象上使用accept_mimetypes.accept_jsonaccept_mimetypes.accept_htmlaccept_mimetypes.accept_xhtml属性。响应的默认内容类型实际上仅取决于您的应用程序是什么;试着想象哪一个会减少混乱。

答案 1 :(得分:0)

这对我们有用:

    if ('text/html' not in environ.get('HTTP_ACCEPT', '')
            and 'application/json' not in response.content_type):
        # the user agent didn't explicitely request html, so we return json
        ...  # make the JSON response

即。如果客户端需要html - 不要返回json。否则返回 json响应,如果响应不是json。