2015-04-08 13 views
13

Invio una richiesta POST con corpo JSON a un server Django (abbastanza standard). Sul server ho bisogno di decodificarlo usando json.loads().Ottieni corpo della richiesta come stringa in Django

Il problema è come ottenere il corpo della richiesta in un formato stringa?

Ho il seguente codice attualmente:

body_data = {} 
if request.META.get('CONTENT_TYPE', '').lower() == 'application/json' and len(request.body) > 0: 
    try: 
     body_data = json.loads(request.body) 
    except Exception as e: 
     return HttpResponseBadRequest(json.dumps({'error': 'Invalid request: {0}'.format(str(e))}), content_type="application/json") 

Tuttavia, questo dà un errore the JSON object must be str, not 'bytes'.

Come si recupera il corpo della richiesta come stringa, con la codifica corretta applicata?

+0

Does request.read() 'esegue il lavoro? – dhke

+0

@ dhke, no, dà lo stesso, che mi ha sorpreso in realtà. 'request.body.decode ('utf-8')' sembra funzionare, ma non sono sicuro se questo è il modo migliore per farlo? – zelanix

risposta

26

Il corpo della richiesta, request.body, è una stringa di byte. In Python 3, json.loads() accetta solo una stringa unicode, quindi è necessario decodificare request.body prima di passarlo a json.loads().

body_unicode = request.body.decode('utf-8') 
body_data = json.loads(body_unicode) 

In Python 2, json.loads accetterà una stringa unicode o di una puntura di byte, quindi il passo di decodifica non è necessario.

Quando decodifica la stringa, penso che tu sia sicuro di assumere 'utf-8' - non riesco a trovare una fonte definitiva per questo, ma si veda la citazione in basso dal jQuery docs:

Nota : La specifica W3C XMLHttpRequest impone che il set di caratteri sia sempre UTF-8; specificare un altro set di caratteri non costringerà il browser a modificare la codifica.

In Python 3.6, json.loads() accepts bytes or bytearrays. Pertanto non è necessario decodificare request.body (supponendo che sia codificato in UTF-8).

+0

Perfetto, grazie per chiarire questo :) – zelanix

+2

'utf-8' è anche il valore predefinito del primo argomento del metodo' decode() '(controlla' help (bytes.decode) ') – rednaw

+2

In Python> = 3.6, 'json.loads' può accettare anche un argomento' bytes', e assume che sia codificato in UTF-8, UTF-16 o UTF-32. https://docs.python.org/3/library/json.html#json.loads – Flimm

0

Credo che l'altra estremità da cui si riceve questa richiesta non converta i dati in JSON prima di inviare la richiesta. O devi convertire i dati in JSON prima di inviarli, o semplicemente provare ad accedere a request.body nella tua vista.

+1

Grazie per la risposta. Penso che sia comunque valido JSON - se uso 'request.body.decode ('utf-8')' allora funziona. C'è una ragione per non farlo, diresti? – zelanix

Problemi correlati