ajax前后端交互的使用已经非常普及了, 这种数据交互方式比表单提交数据带给用户的使用体验更好一些。同时,利用ajax交互时数据传输一般使用json,我们可以很方便的管理我们所需要的数据。只需要定义好数据格式,可以前后端分离开发。
我们这里改一下之前图片上传的代码,使用ajax方式上传图片。
html表单:
<div style="width:100px;float:left;margin-left:35px;"> <form method="post" enctype="multipart/form-data" id="test_form" style="margin-top:45px;"> <a href="javascript:;" class="file button red">选择照片 <input type="file" name="photo" id="photo"> </a> <a type="button" class="file button red" id="tj" onclick="ajaxForm()">上传照片</a> <a class="file button red" data-reveal-id="myModal">手动裁剪</a> </form> </div>
Js代码:
function ajaxForm(){ var form= new FormData(document.getElementById("test_form")); $.ajax({ url:"{{ url_for('api_upload') }}", type:"post", data:form, dataType: 'json', processData:false, contentType:false, success:function(data){ $(img_url_new).attr("src",data.img_url_new); $(imgPic).attr("src",data.img_url_new); }, error:function(e){ alert("error"); } }) }
注意,需要引入jquery。
data为获取的表单数据,以json格式通过post方法传入后台,成功后从后台获取数据data,失败则弹出error。
后台接收代码:
@app.route('/up_photo', methods=['POST'], strict_slashes=False) def api_upload(): file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER']) if not os.path.exists(file_dir): os.makedirs(file_dir) f = request.files['photo'] if f and allowed_file(f.filename): fname = secure_filename(f.filename) ext = fname.rsplit('.', 1)[1] new_filename = Pic_str().create_uuid() + '.' + ext print new_filename f.save(os.path.join(file_dir, new_filename)) img_url = ip+'show/'+new_filename img_url_new = ip+'show/'+new_filename #处理后的图片,假数据 return jsonify({"success": 200, "msg": "上传成功", "img_url": img_url, "img_url_new": img_url_new}) else: return jsonify({"error": 1001, "msg": "上传失败"})
通过上传图片的小例子我们大概了解了Flask使用ajax交互的基本方式,下面通过一个更加符合ajax使用场景的例子来加深理解它。
如,有这样一个场景,我们希望鼠标点击图片时将点击坐标传入后台,这时就必须使用ajax来实现了。
html页面代码:
<div id="myModal" class="reveal-modal"> <h1>点击选择裁剪坐标</h1> <div class="uploader blue"> <img id="imgPic" src="{{ url_for('static', filename='img/1.jpg') }}" onclick="Show(this)" style="width:300px;height:270px;"/> X:<input id="xxx" type="text" style="width:30px;"/> Y:<input id="yyy" type="text" style="width:30px;"/> </div> <a class="close-reveal-modal">×</a> </div>
js代码:
<!--获取图片坐标--> function mousePosition(ev){ if(ev.pageX || ev.pageY){ return {x:ev.pageX, y:ev.pageY}; } return { x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, y:ev.clientY + document.body.scrollTop - document.body.clientTop }; } function mouseMove(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); document.getElementById('xxx').value = mousePos.x; document.getElementById('yyy').value = mousePos.y; } document.onmousemove = mouseMove; function Show(el){ var x = parseInt(document.getElementById('xxx').value)-el.offsetLeft; var y = parseInt(document.getElementById('yyy').value)-el.offsetTop; var data= { data: JSON.stringify({ 'x': x, 'y': y }), } $.ajax({ url:"{{ url_for('img_operate') }}", type:"post", data:data, dataType: 'json', success:function(data){ //成功后的一些操作 }, error:function(e){ alert("error"); } }) }
注意,我们这里通过json格式将数据传入后台:
var data= { data: JSON.stringify({ 'x': x, 'y': y }), }
那么后台如何接收x、y轴坐标呢?
data = json.loads(request.form.get('data')) x = data['x'] y = data['y']
以上为接收ajax前台传入数据的方法,后台路由方法完整代码:
# 坐标操作图片处理的按钮路由 @app.route('/img_operate', methods=['POST']) def img_operate(): data = json.loads(request.form.get('data')) x = data['x'] y = data['y'] print(x) print(y) img = 'http://localhost:5000/static/img/1.jpg' return jsonify({"success": 200, "img": img, "x": x, "y": y})
以上这些介绍了ajax前后台交互的基本方法。