2016-12-30 5 views
2

Eine Ressource mit mehreren Darstellungen (Medientypen), die keine benutzerdefinierten CherryPy-Tools verwenden, um die Interpretation des HTTP-Headers "Accept" und die Serialisierung der Antwort zu verarbeiten Entitätskörpers wirft CherryPy die folgende ValueError Ausnahme auf den Inhalt von der Seite Handler zurückkehrt, nachdem die "Content-Type" HTTP-Header eine entsprechende Einstellung, aber für bestimmte Medientypen nur:Zurückgegebener Inhalt wird nicht automatisch nach Änderung des Inhaltstyps codiert

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

Beispiel:

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

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

Dies funktioniert für beide Medientypen, obwohl die JSON-Darstellung fälschlicherweise als HTML (Standard) deklariert wird.

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

Hier wird die obige Ausnahme ausgelöst, wenn der JSON-Inhalt als Zeichenfolge zurückgegeben wird.

Versuche zu gewährleisten tools.encode ist in der Tat aktiviert und tools.encode.encoding auf utf-8 explizit (auch wenn es die Standardeinstellung ist) fehlschlagen. Die Dinge funktionieren für die HTML-Darstellung, also scheint es, dass es auch für die JSON-Darstellung funktionieren sollte.

Derzeit scheint die Dokumentation für tools.encode eher spärlich, was die beste Vorgehensweise ist, ist nicht sofort offensichtlich.

Antwort

1

Das CherryPy-Codierungstool codiert Inhalte nur dann automatisch, wenn der Medientyp der obersten Ebene text (text/*) ist.

Es gibt eine Möglichkeit, dies mit der encode.text_only Einstellung zu steuern, aber es ist global und kann daher Probleme bei der Rückgabe von Inhalten, die eigentlich nicht codiert werden sollten, einführen. Zum Zeitpunkt dieses Artikels verfolgt ein offenes Problem eine Featureanforderung, um eine genauere Steuerung dieses Verhaltens zu ermöglichen: #1123.

Aus diesem Grunde ist der am besten geeignete Weg, um dies in dieser besonderen Situation zu lösen ist, den Inhalt manuell zu kodieren: eine richtige Antwort auf diesen

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

Bitte markieren. P.S. Fühlen Sie sich frei, eine Pull Request vorschlagen :) – webKnjaZ

+0

@webKnjaZ Danke, ich fühle mich besser, es mit einer Bestätigung zu tun. Eine sehr nützliche PR wäre wahrscheinlich nur eine Dokumentation, aber ich befürchte, dass sich mein Beitrag nicht auf mehr als diese Frage und Antwort erstreckt (was hoffentlich leicht gefunden werden kann, wenn jemand anderes von diesem speziellen Szenario überrascht wird). Für jetzt sowieso ;-). – tne

+0

Wie auch immer, ich habe hier eine Referenz zu diesem Thema platziert – webKnjaZ

Verwandte Themen