【问题标题】:How to determine if client expects a JSON response如何确定客户端是否需要 JSON 响应
【发布时间】:2015-10-09 18:37:42
【问题描述】:

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

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

在这个解决方案中,我依赖于包含字符串'application/json'Content-Type 标头。

但这看起来不像是一个正确的解决方案,因为维基百科说:

Content-Type请求正文的 MIME 类型(用于 POST 和 PUT 请求)

检查'text/html' 是否在标头Accept 中然后返回HTML 响应,否则返回JSON 响应是一个好策略吗?

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

当 Chrome 请求 HTML 页面标题时

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

在 Ember 发出 API 请求时发送

Accept: application/json, text/javascript, */*; q=0.01

已发送。

也许应该考虑X-Requested-With: XMLHttpRequest

【问题讨论】:

    标签: python http http-headers mime-types


    【解决方案1】:

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

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

    【讨论】:

    • 感谢AcceptMixin 的提示,但我的问题是如何使用AcceptMixin.accept_mimetypes 提供的信息。当 Chrome 请求 HTML 页面时发送 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',当 Ember 发出 API 请求时发送 'HTTP_ACCEPT': 'application/json, text/javascript, */*; q=0.01'。在这两种情况下request.accept_mimetypes.accept_json == request.accept_mimetypes.accept_html == True
    【解决方案2】:

    这对我们有用:

        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。

    【讨论】:

      猜你喜欢
      • 2021-04-24
      • 2015-06-08
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多