Question

I am trying an html page to interact with a python script which returns a json string, using ajax/jquery. I installed bottle for the basic functionality of url routing.

The problem is that my browser shows that my ajax script is recieving a content-length of 5 (which is the string "tring" (see server.py function showAll()) but somehow its not stored in the variable result(see function loader in script.js) and hence I cannot use the returned data.

can anyone tell me what is going wrong..

my html file looks like

index.html

<!DOCTYPE>
<html>
    <head>
        <title>
            magpie
        </title>
        <script type="text/javascript" src="js/script.js"></script>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script type="text/javascript">loader();</script>
    </head>
    <body>
        <div id="main"></div>
    </body>
</html>

If I call load() instead of loader() in this file the content is displayed.

the ajax script:

script.js

function loader()
{
    $(document).ready(function(){
        $.get('http://[localhost]:1111/', function(result){
            alert('success');
            $('#main').html(result);
        });
    });
}

function load()
{
    $(document).ready(function () {
        $.getJSON('data.json', function (data) {
            var output = '';
            $.each(data, function(key, val) {
                output += '<h3>' + val.device + '  ' + val.status + '</h3>';
            })
            $('#main').html(output);
        });
    });
}

the two python scripts are :

server.py

from bottle import get, post, request, run, response
import devices

@get('/')
def showAll():
    # return devices.data
    return "tring"

@post('/act')
def act():
    deviceId = request.forms.get('deviceId')
    devices.changeState(deviceId)
    return

run(host = "[localhost]", port = 1111)

devices.py

import json

data = json.load(open('data.json', 'r+'))
nos = len(data) # Number of devices

def changeState(id):
    state = data[id]['status']
    if state == 'on':
        data[id]['status'] = 'off'
    else:
        data[id]['status'] = 'on'

    json.dump(data, open('data.json', 'w'))

    return 1

and finally my json file(if it matters):

{"B1": {"device": "fan", "status": "on"}, "B3": {"device": "light", "status": "off"}, "B2": {"device": "fan", "status": "on"}}

Loading http://[localhost]:1111/ in browser shows the returned string "tring".Also the page loads only in firefox while other browsers show some allow-acces-origin error.

This is a screenshot of my browser :

enter image description here

Was it helpful?

Solution 3

I had to enable the accessControlAllowOrigin header (thanks to @user3202272, I got the hint from your answer).

Added a few lines to my server.py file and that was it.

Now it looks like

server.py

from bottle import Bottle, request, response, run
import devices

app = Bottle()

@app.hook('after_request')
def enable_cors():
    response.headers['Access-Control-Allow-Origin'] = '*'

@app.get('/')
def show():
    return devices.data
    # return "tring"

@app.post('/act')
def act():
    deviceId = request.forms.get('deviceId')
    devices.changeState(deviceId)
    return

app.run(host = "0.0.0.0", port = 1111)

So basically the problem was with the CORS. You can read more about it here https://gist.github.com/richard-flosi/3789163

Bottle Py: Enabling CORS for jQuery AJAX requests

thanks to everyone..!! :D

OTHER TIPS

how is your browser recieving "tring" when you are returning "string" from your python script.

I think you will have to set

accessControlAllowCredentials true

I suppose

Your server is not returning json; it's returning text/html.

Instead of this:

return "tring"

return a dict, like this:

return {"result": "tring"}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top