-1

I feel like I'm missing something terribly obvious, but I can't see it.

In ipython (Python 2.7), this works:

In [1]: json.loads('[]')
Out[1]: []

I'm trying to do the equivalent minimal example in a Django view, to convince myself I can read JSON before moving on to a real data structure:

def submit(request):
    json_string = request.GET['json']
    parsed = json.loads(json_string)

    return HttpResponse(parsed)

I call it from my browser by going to

http://localhost:8001/submit/?json='[]'

And I get ValueError: No JSON object could be decoded.

What am I doing wrong, and how do I debug it? Is this some kind of encoding problem? Or am I accessing the content of the GET incorrectly? Or something else?

I've tried dumping the variable json_string, both to a file and as an HttpResponse. Both times I get '[]', which sure looks fine...

Edit:

For the benefit of any other beginners wondering how to debug a POST, Django's error page is returned in the exception. A quick and nasty hack that works is

import os
def debug_post(post_req):

    result = None
    try:
        result = submit_to_endpoint(post_req)
    except urllib2.URLError as e:
        out_fh = open('debug_post.tmp', 'w')
        out_fh.write(e.read())
        out_fh.close()
        os.system('firefox ' + 'debug.tmp')

    return result
ire_and_curses
  • 68,372
  • 23
  • 116
  • 141

2 Answers2

3

You've included the single quotes in the JSON string. There's no need for that, especially as single quotes are not valid in JSON. You should go to http://localhost:8001/submit/?json=[].

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Ok, this works. So in the ipython example, the single quotes represent a Python string, but in the GET request, they are being passed in as literal characters, is that right? – ire_and_curses Oct 01 '12 at 11:47
  • @ire_and_curses Yup - that's right. You are going to be using POST for real JSON data though, right? – Jon Clements Oct 01 '12 at 11:48
  • @Jon Clements - I certainly can do. Is there a reason to prefer it (can you tell I'm new to this)? – ire_and_curses Oct 01 '12 at 11:49
2

Although GET may seem easier even for testing purposes, for JSON you should use POST requests. This is very important in a case where the requests chage the internal state of the application. E.g. /localhost/format/?json={disk_id : 1} is something that changes the state of the application :) Usually search engines index websites' links which are GET requests. Imagine a link like that being indexed by a search engine: even during the indexing process the internal state of the application can be changed.

Another reason is the URLS caching implemented by web servers, proxies and browsers. And guess what, the GET requests' responses is what generally gets cached.

Last but not least, GET request arguments are expected to be simply in Query string

localhost?key1=val1&key2=val2

format, where val's are single-valued data fields, not JSON data.

So, the reason is in the HTTP protocol design. You can utilize e.g. AJAX techniques to POST JSON data and that'll be enough to avoid everything described above.

I recommend you getting acquainted with the idea of RESTful web services - an easy yet powerful concept of designing user-to-webapp communication.

Zaur Nasibov
  • 22,280
  • 12
  • 56
  • 83
  • Thanks, this is helpful. It also looks like I hit a [character limit](http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url) when dumping a pre-constructed url through Firefox. I've switched to POST now. – ire_and_curses Oct 01 '12 at 18:17
  • For future REST beginners, I note also that I found a simple way to debug the POST output that gives similar functionality to the GET. See my edit. – ire_and_curses Oct 01 '12 at 18:23