2016-12-30 2 views
2

Учитывая ресурс с несколькими представлениями (типами носителей), который не использует специальные инструменты CherryPy для обработки интерпретации HTTP-заголовка Accept и сериализации ответа сущность тела, CherryPy поднимает следующий ValueError исключение по возвращении содержимого из обработчика страницы после установки «Content-Type» заголовок HTTP надлежащим образом, но только для определенных типов носителей:Возвращаемое содержимое, не закодированное автоматически после изменения Content-Type

ValueError: Page handlers MUST return bytes. Use tools.encode if you wish to return unicode.

Пример:

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

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

Это работает для обоих типов носителей, хотя представление JSON будет ошибочно объявлено как HTML (по умолчанию).

Здесь приведенное выше исключение возникает при возврате содержимого JSON в виде строки.

Попытки гарантировать, что tools.encode действительно включены, и установка tools.encode.encoding в utf-8 явно (хотя и по умолчанию) сбой. Вещи работают для представления HTML, поэтому кажется, что он должен работать и для представления JSON.

В настоящее время документация для tools.encode выглядит довольно редкой, поэтому лучший подход к ней не сразу становится очевидным.

ответ

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

Пожалуйста, отметьте это правильный ответ. Постскриптум Не стесняйтесь предлагать запрос Pull :) – webKnjaZ

+0

@webKnjaZ Спасибо, мне лучше сделать это с подтверждением. Самый полезный PR, вероятно, будет всего лишь исправлением документации, но я боюсь, что мой вклад не будет распространяться на большее, чем этот Q & A (который, надеюсь, можно легко найти, если кто-то еще удивится этому конкретному сценарию). На данный момент все равно ;-). – tne

+0

В любом случае, я разместил здесь ссылку на этот вопрос – webKnjaZ

 Смежные вопросы

  • Нет связанных вопросов^_^