Question

I'm trying to get bottle to receive json in an xmlhttprequest and I'm getting a 405 error

Part of my bottle script:

@app.route('/myroute/')
def myroute():
    print request.json

Part of my other script to test the xhr out:

jdata = json.dumps({"foo":"bar"})
urllib2.urlopen("http://location/app/myroute/", jdata)

Why am I getting a 405?

bottlepy error: 127.0.0.1 - - [2012-09-23 23:09:34] "POST /myroute/ HTTP/1.0" 405 911 0.005458

urllib2 error: urllib2.HTTPError: HTTP Error 405: Method Not Allowed

I also tried variations of:

@app.route('/myroute/json:json#[1-9]+#')
def myroute(json):
    request.content_type = 'application/json'
    print request.json, json

Returning json does not seem to be an issue

Était-ce utile?

La solution

I think the problem is the server does not allow POST requests. You can probably try sending it in a GET request instead:

urllib2.urlopen("http://location/app/myroute/?" + jdata)

UPDATE:

I just realized, after looking at your question again, that you are actually trying to send JSON data via GET request. You should in general avoid sending JSONs with GET requests, but use POST requests instead[Reference].

To send a POST request to Bottle, you also need to set the headers to application/json:

headers = {}
headers['Content-Type'] = 'application/json'
jdata = json.dumps({"foo":"bar"})
urllib2.urlopen("http://location/app/myroute/", jdata, headers)

Then, with the help of @Anton's answer, you can access the JSON data in your view like this:

@app.post('/myroute/')
def myroute():
    print request.json

Also, as a bonus, to send a normal GET request and access it:

# send GET request
urllib2.urlopen("http://location/app/myroute/?myvar=" + "test")

# access it 
@app.route('/myroute/')
def myroute():
    print request.GET['myvar'] # should print "test"

Autres conseils

By default, the route decorator makes the decorated function handle only GET requests. You need to add a method argument to tell Bottle to handle POST requests instead. To do that, you need to change:

@app.route('/myroute/') 

to:

@app.route('/myroute/', method='POST')

or a shorter version:

@app.post('/myroute/')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top