2015-07-20 1 views
1

В моем приложении Werkzeug я перехватывающий все ошибочные ответы и пытаюсь ответить с ответом JSON, если клиент ожидает JSON или вернуть обычную HTML-страницу с 404 или 500:Как определить, является ли клиент ожидает ответ 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, содержащий строку 'application/json'.

Однако это не выглядит как правильное решение, потому что Википедия говорит:

Content-Type мим тип тела запроса (используется с 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 

отправляется, когда угасающий делает запрос API

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

отправляется.

Может быть, необходимо принять во внимание X-Requested-With: XMLHttpRequest?

ответ

0

Возможно, вы добавите AcceptMixin в ваш объект запроса.

Как только вы сделаете это, вы можете использовать атрибуты accept_mimetypes.accept_json, accept_mimetypes.accept_html и accept_mimetypes.accept_xhtml на свой объект запроса. Тип контента по умолчанию для ответа зависит только от того, что ваше приложение; просто попытайтесь представить, что приведет к меньшему путанице.

+0

Спасибо за подсказку о '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 request ''HTTP_ACCEPT': 'application/json, text/javascript, */*; q = 0.01''. И в обоих случаях 'request.accept_mimetypes.accept_json' ==' request.accept_mimetypes.accept_html' == 'True'. – warvariuc

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.