[bottle] json data request

Django, Flask, Bottle, WSGI, CGI…
Antworten
christKIN_D
User
Beiträge: 10
Registriert: Dienstag 4. August 2009, 06:01
Wohnort: Erlangen

Ich wollte mal bottle.py mit jQuery&Ajax ausprobieren, darum habe ich mein Setup so minimal aufgebaut wie möglich.
Dictionarys werden von bottle automatisch als Typ 'application/json' ausgeliefert, das funktioniert auch. Wenn ich mein javascript ausführe, geht auch ein request an meinen bottle-server. Aber statt alert('whoooo es geht'), lande ich immer beim error. Was mache ich falsch?

Code: Alles auswählen

@route('/json/test')
def show_json():
    return {'TestA':'Ich bin Test A.', 'TestB':'Ich bin Test B.'}

Code: Alles auswählen

 <script type="text/javascript">                                         
	$.ajax({
	  type: "GET",
	  url: "http://127.0.0.1:8080/json/test",
	  dataType: 'json',
	  success: function(data){
		alert('whoooo es geht');
	  },
	  error: function(o,c,m) { alert(m); }
	});
 </script>

Code: Alles auswählen

Bottle v0.11.dev server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:8080/
Hit Ctrl-C to quit.

localhost - - [07/May/2012 14:17:28] "GET /json/test HTTP/1.1" 200 56
localhost - - [07/May/2012 14:19:32] "GET /json/test HTTP/1.1" 200 56
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Du möchtest dir mal das JSON Modul ansehen ;) denn dein Dict ist kein valides JSON (' vs "), trotz des richtigen Headers.

EDIT
Sowas kann man auch prima mit FireBug (Firefox Extension) herausfinden ...
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Klar ist das valides JSON …

Das Problem ist möglicherweise die „Same-Origin-Policy“.

Wenn du deine HTML-Datei über Bottle auslieferts funktionierts:

Code: Alles auswählen

from bottle import route, run, static_file

@route('/')
def index():
    return static_file("test.html", root='.')

@route('/json/test')
def show_json():
    return {'TestA':'Ich bin Test A.', 'TestB':'Ich bin Test B.'}

run(host='localhost', port=8080)
christKIN_D
User
Beiträge: 10
Registriert: Dienstag 4. August 2009, 06:01
Wohnort: Erlangen

Danke nomnom! An so etwas wie eine „Same-Origin-Policy“ hatte ich nicht gedacht.
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

nomnom hat geschrieben:Klar ist das valides JSON …
Klar ist nur, dass das kein valides JSON ist. Bloss weil es geht ist das noch lange nicht richtig. Wie ich oben schon schrieb, müssen Zeichenketten für JSON in "Double-Quotes" stehen. Sich auf die automatische Umwandlung von dict nach str zu verlassen ist fahrlässig. Deshalb sollte man vor der Respone explizit seine Daten JSON-kompatibel machen. Nur noch mal zur Verdeutlichung:

Code: Alles auswählen

>>> json.dumps({'a':'b', 'c':'d'})
'{"a": "b", "c": "d"}'
Jaja, ich weiss, pingelig, aber nicht jeder JSON Parser akzeptiert Singlequotes :)

Code: Alles auswählen

>>> json.loads("{'a':'b', 'c':'d'}")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/local/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 1 (char 1)
>>> json.loads('{"a":"b", "c":"d"}')
{u'a': u'b', u'c': u'd'}
deets

frabron hat geschrieben:
nomnom hat geschrieben:Klar ist das valides JSON …
Klar ist nur, dass das kein valides JSON ist. Bloss weil es geht ist das noch lange nicht richtig.
Stimmt nicht. Du verwechselst Python-Literale mit der JSON-encodierung. Der OP hat eine *PYTHON* Struktur zurueckgegeben, und bottle wandelt das automatisch. Da ist auch nix "fahrlaessiges" dran - im Gegenteil, das von Hand zu machen ist boiler-plate & fehleranfaelliger. Natuerlich muss man sicherstellen, dass der JSON-serialisierer auch alle Objekte serialisieren kann. Aber das muss man beim expliziten dumps ja auch...
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Mir war nicht bewusst, dass Bottle sowas automatisch macht, aber ich habe grade die entsprechende Stelle in der Dokumentation gefunden. Das habe ich dann wohl mit Flask ein wenig durcheinander gebracht, wo man explizit JSON mittels flask.jsonify zurückgeben muss ...
Antworten