如何在Brython中使用Ajax

7
我正在使用Flask编写一个Web应用程序,想要在Brython中使用浏览器.ajax功能,但找不到可行的示例。如果有人能演示如何在Brython中使用ajax的简短示例,那就太好了。更具体地说,如何通过单击提交按钮将用户输入的数据传递到文本区域。非常感谢任何帮助!
(我在发布上面的问题几周后写下了这篇文章)。我按照这个Flask中实现ajax的教程(http://runnable.com/UiPhLHanceFYAAAP/how-to-perform-ajax-in-flask-for-python)尝试将jquery.ajax替换为Brython。不幸的是,我仍然无法让它工作。以下是我的代码:
Flask部分:
@app.route('/')
def index():
    return render_template('index.html')

@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)

Brython/HTML:

 <body onload="brython()">
 <script type="text/python">
 from browser import document as doc
 from browser import ajax

def on_complete(req):
    if req.status==200 or req.status==0:
        doc["txt_area"].html = req.text
    else:
        doc["txt_area"].html = "error "+req.text

def get(url):        
    req = ajax.ajax()
    a = doc['A'].value        
    b = doc['B'].value
    req.bind('complete',on_complete)
    req.open('GET',url,True)
    req.set_header('content-type','application/x-www-form-urlencoded')
    req.send({"a": a, "b":b})      

doc['calculate'].bind('click',lambda ev:get('/_add_numbers'))

</script>

<div class="container">
  <div class="header">
    <h3 class="text-muted">How To Manage JSON Requests</h3>
  </div>
  <hr/>
  <div>
  <p>
<input type="text" id="A" size="5" name="a"> +
<input type="text" id ="B" size="5" name="b"> =
<textarea type="number" class="form-control" id="txt_area" cols="10" rows = '10'></textarea>
<p><a href="javascript:void();" id="calculate">calculate server side</a>

  </div>
 </div>
 </body>
</html>

我得到的是"result":0。看起来brython没有将数据发送到Flask的视图函数中,但我不知道如何修复它。因此,如果有人能指出我具体做错了什么,那就太好了。
2个回答

6

在您的示例中,Ajax请求使用GET方法发送。在这种情况下,send()的参数将被忽略:数据必须在附加到URL的查询字符串中发送。

Brython代码应该是:

def get(url):        
    req = ajax.ajax()
    a = doc['A'].value        
    b = doc['B'].value
    req.bind('complete',on_complete)
    # pass the arguments in the query string
    req.open('GET',url+"?a=%s&b=%s" %(a, b),True)
    req.set_header('content-type','application/x-www-form-urlencoded')
    req.send()

如果你想使用POST方法,那么Brython代码可以不变,但Flask代码需要进行修改:你必须指定该函数处理POST请求,并通过属性"form"获取参数而非"args":
@app.route('/_add_numbers_post', methods=['POST'])
def add_numbers_post():
    a = request.form.get('a', 0, type=int)
    b = request.form.get('b', 0, type=int)
    return jsonify(result = a+b)

非常感谢!它起作用了!我唯一的问题是:我需要在查询字符串中手动包含参数(在这种情况下为“?a =%s&b =%s”),还是可以自动完成?再次感谢! - chemist
你应该真正偏爱使用Post方法。无论如何,是的,参数必须“手动”包含 - 浏览器只“知道”收集表单值并在重新加载整个页面的事件中提交它们。 - jsbueno
有人知道如何设置头文件吗?我需要正确地设置以下网站的头文件:https://developer.oxforddictionaries.com/ - sqp_125

3

我正在研究这个 - 没有现成的东西可用,但编写Python代码使它变得非常简单。

我无法发布我正在工作的代码(而且与最小限度相去甚远)- 但基本上,您可以编写一个(Br)Python函数来迭代HTML或form DOM,并收集所有具有“value”的内容到类似JSON的结构中(一个带有嵌套字典和列表的字典),然后只需按照http://brython.info/doc/en/index.html#文档中所述使用browser.ajax对象,并将带有数据的对象作为参数传递给“send”方法。

对象数据将在请求正文中进行URL编码。您只需从其中转换为JSON即可在客户端上解码。

作为额外提示: 我没有深入探讨问题,但我觉得默认使用的URL编码可能无法表达JSON中所可能的所有内容。因此,我导入了brython的json模块,并像这样执行发送:

ajax_object.send({"data": json.dumps(json_data)})

这使我可以在客户端上执行以下操作: json_data = json.loads(urllib.unquote(request.body).split(":",1)[-1] )

(“request.body”来自Pyramid - 对于flask来说,只有在flask无法理解内容类型时才是“request.data”,请参见How to get data received in Flask request


非常感谢您的回复。我刚刚更新了我的问题,并包含了一个Flask / brython示例。但仍无法让它工作。 - chemist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接