Flask与JavaScript
我正在用Flask开发一个网页服务器应用程序。到目前为止,我创建了一个小框架,用户可以在图片上用画布和JavaScript画一些框。我把这些框的信息和图片的信息都保存在JavaScript的一个数组里。不过,这些数据必须提交并存储到服务器端的数据库里。因此,我有一个按钮可以提交这些内容,但我不知道怎么获取我在JavaScript里保存的数据,也就是框和图片的信息。
这样获取JavaScript的信息并提交,是否可行呢?我想过一些办法,比如把信息打印在隐藏的HTML元素里,或者使用AJAX把信息发送到服务器,但我觉得这些方法可能不是在Flask中处理这个问题的“正确”方式。那么,有人有什么想法吗?以下是我认为可能与理解我的问题相关的部分代码:
Models.py:我这里的类有点不同:Blindmap=Image,Label=boxes。我的数据库是用SQLAlchemy建模的。
blindmap_label = db.Table('blindmap_label',
db.Column('blindmap_id', db.Integer, db.ForeignKey('blindmap.id', ondelete = 'cascade'), primary_key = True),
db.Column('label_id', db.Integer, db.ForeignKey('label.id', ondelete = 'cascade'), primary_key = True))
class Blindmap(db.Model):
__tablename__ = 'blindmap'
id = db.Column(db.Integer, primary_key = True)
description = db.Column(db.String(50))
image = db.Column(db.String)
labels = db.relationship('Label', secondary = blindmap_label, backref = 'blindmaps', lazy = 'dynamic')
def __init__(self, label = None, **kwargs):
if label is None:
label = []
super(Blindmap, self).__init__(**kwargs)
def add_label(self, label):
if label not in self.labels:
self.labels.append(label)
db.session.commit()
def __repr__(self):
return '<Blindmap %r:>' % (self.id)
class Label(db.Model):
__tablename__ = 'label'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(50))
x = db.Column(db.Integer)
y = db.Column(db.Integer)
w = db.Column(db.Integer)
h = db.Column(db.Integer)
def __repr__(self):
return '<Pair %r:>' % (self.id)
我的控制器信息:
@app.route('/')
@app.route('/index')
def index():
blindmaps = db.session.query(Blindmap).all()
return render_template("index.html",
title = 'Home',
blindmaps = blindmaps)
@app.route('/new', methods = ['GET', 'POST'])
def new():
form = BlindmapForm()
if request.method=="POST":
if form.validate_on_submit():
blindmap = Blindmap(description=form.description.data)
redirect(url_for('index'))
return render_template("new.html",
title = 'New Blindmap',
form=form)
2 个回答
你需要做的是使用AJAX,这是一种技术,可以在网页加载到用户的浏览器后“异步”地发送请求并从服务器获取响应,使用的是JavaScript。AJAX实际上是“异步JavaScript和XML”的缩写(虽然它不一定完全是异步的,也不一定非得使用XML作为数据交换格式)。这是访问网络API的标准方式,比如你用Flask创建的API,通过URL(也就是路由)来获取和保存后端的对象。
现代浏览器都提供了一个叫做XMLHttpRequest的构造函数(MDN文档),可以用来创建对象,让网页在加载后与网络服务器进行通信。
为了提高不同浏览器之间的兼容性和代码的可维护性,你可以使用一些JavaScript框架,它们会把XMLHttpRequest封装成更简单的形式。我这些年来一直在有效地使用jQuery来实现这个目的。特别是,在你的情况下,你需要使用jQuery.ajax方法(或者对于POST操作,可以用它的简写jQuery.post)。
不过,我会给你一个小例子,展示如何使用原生JavaScript来执行这样的请求,这样即使在使用框架时,你也能理解浏览器里发生了什么:
// Create an instance of the XHR object
var postNewObject = new XMLHttpRequest();
// Define what the object is supposed to do once the server responds
postNewObject.onload = function () {
alert('Object saved!');
};
// Define the method (post), endpoint (/new) and whether the request
// should be async (i.e. the script continues after the send method
// and the onload method will be fired when the response arrives)
postNewObject.open("post", "/new", true);
// Send!
postNewObject.send(/* Here you should include the form data to post */);
// Since we set the request to be asynchronous, the script
// will continue to be executed and this alert will popup
// before the response arrives
alert('Saving...');
想了解更多关于使用XMLHttpRequest的信息,可以参考MDN。
试试用 jQuery 的 ajax:
function upload() {
// Generate the image data
var img= document.getElementById("myCanvas").toDataURL("image/png");
img = img.replace(/^data:image\/(png|jpg);base64,/, "")
// Sending the image data to Server
$.ajax({
type: 'POST',
url: '/upload', // /new
data: '{ "imageData" : "' + img + '" }',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (msg) {
// On success code
}
});
}
接下来是在服务器端获取上传的图片数据,方法是使用 request.json['imageData'],然后把它存储到数据库里。
img = request.json['imageData'] # Store this in DB (use blob)