ajax的python烧瓶示例

For a while now I am trying to learn how to use Ajax with Flask. On the official website of flask there is an example:

from flask import Flask, jsonify, render_template, request
app = Flask(__name__)

@app.route('/_add_numbers')
def add_numbers():
    a = request.args.get('a', 0, type=int)
    b = request.args.get('b', 0, type=int)
    return jsonify(result=a + b)

@app.route('/')
def index():
    return render_template('index.html')

It works for me well. But I am looking for the following program:

  1. a jQuery code sends an initial number to the python app
  2. the python app stores the number and responds 'received: [the number]'
  3. while true: the python app waits for requests 'increase' for which it adds 1 to the number and returns it

The jQuery part doesn't matter, I can do that but I am not sure how to implement the python part:

@app.route('/_inc_number')
def inc_number():
    n = request.args.get('n', 0, type=int)
    while true:
        req = request.args.get('req', 0, type=string)
        if req == 'increase':
            n = n + 1
            return n #It exits the function. how respond without quit?

Please explain me how I can data back? I am new to both Ajax and Flask too, and I suspect that it is not "real" ajax...Is that right? How would you implement a simple function with the same functionality in flask?

HTTP requests don't have a memory, they are independent of each other. It means when your Python app gets a request, it does something, sends a response immediately and quits. That's the nature of HTTP.

If you want something persistent (like your number) that lives through more requests, you need:

  • Persistent storage on the server. It can be a file, a database, or in case of Flask simply an object (variable) in memory.
  • Identify the user between separate requests. That's what session handling and cookies are for.

A very primitive method (shouldn't be used on production system):

  • persistent storage: create a global dict (called num) in main()
  • in index():
    • create a random session identifier (si)
    • set num[si] = 0
    • send si as a cookie
  • in inc_number() use si from cookie (sent back by the browser) to increase the appropriate num[si]

I think what you are missing is that each time the client requests a number increase there is an independent request. Your inc_number handler would be coded as follows:

@app.route('/_inc_number')
def inc_number():
    n = request.args.get('n', 0, type=int)
    n = n + 1
    return n

Then from the jQuery side you have to invoke an independent Ajax request each time you want to increase the number.

Note that with this type of solution the jQuery app is the one that keeps track of the current value of the counter, and it has to send it to Flask with each request. Another possibility would be to have the Flask side remember the number in a user session. For that type of solution your Flask app would have two view functions:

from flask import session
# you need to set a SECRET_KEY in configuration, used to sign the user session

@app.route('/set_number')
def set_number():
    # store n in the user session
    session['n'] = request.args.get('n', 0, type=int)

@app.route('/inc_number')
def inc_number():
    session['n'] = session['n'] + 1
    return session['n']

With this solution now jQuery can set the number and not have to send it every time when it invokes inc_number.

I hope this helps.