flask与javascript及ajax
Posted 木林森__
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask与javascript及ajax相关的知识,希望对你有一定的参考价值。
flask与javascript及ajax
1. flask+js
1.1. 最简单的
最简单的元素信息改变。
{% block content %}
<h1>我的第一张网页</h1>
<p id="demo">我的第一个段落</p>
<script>
document.getElementById("demo").innerhtml="我的第一段 JavaScript";
</script>
{% endblock %}}
1.2. 进阶
后端:
@app.route(\'/js\')
def js_t():
return render_template(\'js.html\')
前端:js.html
{% extends \'base.html\' %}
{% block content %}
<h1>我的第一张网页</h1>
<p id="demo">我的第一个段落</p>
<img
src="{{url_for(\'static\',filename=\'img/a.jpg\')}}"
alt="图片缺失" width="200" heigth="300">
<button
type="button"
onclick="displayDate()">显示日期</button>
<p id = \'de\'>{{url_for(\'static\',filename=\'js/js_sample.js\')}}</p>
<script
src="{{url_for(\'static\',filename=\'js/js_sample.js\')}}"
type="text/javascript"
defer></script>
<script>
document.getElementById("demo").innerHTML="我的第一段 JavaScript";
</script>
{% endblock %}}
包含一些元素的展示,引用外部js文件
<script src="{{url_for(\'static\',filename=\'js/js_sample.js\')}}" type="text/javascript" defer></script>
src属性代表文件指向;{{}}代表jinjia2的解释;
url_for代表flask的路径生成;
defer代表待页面加载完成后才执行脚本,否则可能出现找不到元素的问题。
2. flask+ajax
ajax依赖于XMLHTTPRequest,它有一套规则去沟通浏览器与后端,但一般引用jquery就可以了。
ajax使用环境配置
这里使用的是jquery库:https://code.jquery.com/jquery-3.3.1.min.js
网页源码文件中引用:
<script src="{{url_for(\'static\',filename=\'js/jquery-3.3.1.min.js\')}}"></script>
前端代码:
<!DOCTYPE html>
<html
lang="en">
<head>
<meta charset="UTF-8">
<title>Jquery Ajax Test</title>
<script
src="{{url_for(\'static\',filename=\'js/jquery-3.3.1.min.js\')}}"></script>
<script>
$(document).ready(function(){
$(".btn1").click(function(){
$.get("/mystring",function(data,
status){
alert("数据:
" + data + "\\n状态:
" + status);
});
});
$(".btn2").click(function(){
$.get("/mydict",function(data,
status){
alert("name:
" + data.name + "
age:" + data.age);
});
});
$(".btn3").click(function(){
$.get("/mylist",function(data,
status){
alert("name:
" + data[0]+ " age:" + data[1]);
});
});
$(".btn4").click(function(){
$.ajax({url:"/mystring", data:{"mydata": "test"},success:function(data){
alert(data);
}});
});
$(".btn6_2").click(function(){
$.ajax({url:"/dataFromAjax", data:{"mydata": "test
data"},success:function(data){
alert(data);
}});
});
$(".btn5").click(function(){
$.ajax({url:"/mydict", success:function(data){
alert("name:
" + data.name + "
age:" + data.age);
}});
});
$(".btn6").click(function(){
$.ajax({url:"/mylist", success:function(data){
alert("name:
" + data[0] + " age:" + data[1]);
}});
});
$(".btn7").click(function(){
$("p").load("../static/test.txt");
});
$(".btn10").click(function(){
$("p").load("/mystring");
});
$(".btn8").click(function(){
$.getJSON("/mydict",function(data){
$.each(data, function(i,
field){
$("div").append(field + "
");
});
});
});
$(".btn9").click(function(){
$.post("/mydict", function(data,
status){
alert("name:
" + data.name + "
age:" + data.age);
});
});
});
</script>
</head>
<body>
<h1>Ajax Test</h1>
<button class="btn1">get
string</button>
<button class="btn2">get dict</button>
<button class="btn3">get list</button> <br/><br/>
<button class="btn4">ajax
string</button>
<button class="btn5">ajax dict</button>
<button class="btn6">ajax list</button>
<button class="btn6_2">ajax
sentDataToFlask</button><br/><br/>
<p>load:</p>
<button class="btn7">load from file</button>
<button class="btn10">load</button><br/><br/>
<div>getJson: </div><br/>
<button class="btn8">getJson</button><br/><br/>
<button class="btn9">post</button>
<script>
for (p in $(\'.btn1\')){
console.log(p);
}
document.write(\'btn1的文字为:\'+$(\'.btn1\').text())
</script>
</body>
</html>
后端:
# ajax test
@app.route(\'/ajax\')
def ajax():
return render_template(\'ajax_test.html\')
@app.route(\'/mystring\')
def mystring():
return \'my
string\'
@app.route(\'/dataFromAjax\')
def dataFromAjax():
test = request.args.get(\'mydata\')
print(test)
return \'dataFromAjax\'
@app.route(\'/mydict\', methods=[\'GET\', \'POST\'])
def mydict():
d = {\'name\': \'xmr\', \'age\': 18}
return jsonify(d)
@app.route(\'/mylist\')
def mylist():
l = [\'xmr\', 18]
return jsonify(l)
# error handle
@app.errorhandler(404)
def page_not_found(error):
return \'404\'
3. 问题
3.1. 关于$
$( \'a \') 相当于 document.getElementById( \'a \')
这是用了某些组件后那些组件支持的符号,比如DWR
$其实是一个函数名,就是用来获取部件里面的值 $()= document.getElementById()
$在JS中本身只是一个符号而异,在JS里什么也不是。
但在JS应用库JQUERY的作者将之做为一个自定义函数名了,这个函数是获取指定网页元素的函数,使用非常之频繁,所以好多新手不知道,还以为$是JS的什么特殊语法。
后来,可能有些程序员JQUERY用得多了,发现$这个函数很好用,很方便,所以,在不用JQUERY的情况,一般自己也会自定义一个$函数。
即:
在jquery中它的代码是:
function( selector, context ) { // The jQuery object is actually just the init constructor \'enhanced\' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }
作用是选择一个元素,$(“.name”)为类选择器,$(“id”)为id选择
3.2. 关于.val
text():获取或者改变指定元素的文本
html():获取或改变指定元素的html元素以及文本
val():获取或者改变指定元素的value值(一般是表单元素)
以上3个都是jquery类库中的语法
3.3. js文件不生效
有可能缓存没清除,还是使用之前的脚本,需要清除缓存。
3.4. 关于BUTTON-修改button显示文字
button有两种类型
<input type="button" id="btn1" value="按钮"/>
<button id="btn1">按钮</button>
修改方法
document.getElementById("btn1").value="新按钮";
document.getElementById("btn1").innerHtml="新按钮";
3.5. JS函数
getelementbyclassname返回的是一个元素列表,可用item(0)来进行选择。
typeof()查看类型
console.log(‘’) 控制台输出,在F12调试模式下便于调试
for 循环语法:
for (p in $(\'.btn1\')){
console.log(p);
}
4. jquery
JQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。JQuery设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。
它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。
JQuery的核心特性可以总结为:具有独特的链式语法和短小清晰的多功能接口;具有高效灵活的css选择器,并且可对CSS选择器进行扩展;拥有便捷的插件扩展机制和丰富的插件。jQuery兼容各种主流浏览器,如IE 6.0+、FF 1.5+、Safari 2.0+、Opera 9.0+等。
它的使用非常简单,下载库并在前端引用即可。
4.1. 选择器
选取 HTML 元素,并对选取的元素执行某些操作。
基础语法: $(selector).action()
美元符号定义 jQuery
选择符(selector)"查询"和"查找" HTML 元素
jQuery 的 action() 执行对元素的操作
实例:
$(this).hide() - 隐藏当前元素
$("p").hide() - 隐藏所有 <p> 元素
$("p.test").hide() - 隐藏所有 class="test" 的 <p> 元素
$("#test").hide() - 隐藏所有 id="test" 的元素
4.2. 事件
html中的事件是指页面对不同访问者的响应。
常见 DOM 事件:
鼠标事件 |
键盘事件 |
表单事件 |
文档/窗口事件 |
常用的 jQuery 事件方法
$(document).ready()
$(document).ready() 方法允许在文档完全加载完后执行函数。
在示例代码中也使用了这一方法。
click()
click() 方法是当按钮点击事件被触发时会调用一个函数。
该函数在用户点击 HTML 元素时执行。
在下面的实例中,当点击事件在某个 <p> 元素上触发时,隐藏当前的 <p> 元素:
4.3. jquery与ajax
执行异步 AJAX 请求 |
$.get(url, data, callback)
参数 描述
url 必需,规定您需要请求的URL
data 可选,规定连同请求发送到服务器的数据,格式是json
callback 可选,回掉函数,当请求成功时运行的函数
$.post(url, data, callback)
参数 描述
url 必需,规定您需要请求的URL
data 可选,规定连同请求发送到服务器的数据,格式是json
callback 可选,回掉函数,当请求成功时运行的函数
5. 关于ajax
以前写过一篇ajax的笔记,有一个大概的了解,今天写一下其具体实现原理。
ajax的核心是与服务器交换数据及更新网页。
更新网页都是在浏览器上进行的,只要有合适的脚本语言且解释器支持,还是比较好办的,目前而言这一部分的前置技术是css,html,dom,js。
ajax的关键是交换数据,即通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据。获得数据然后用js来操作DOM而更新页面。
首先,我们先来看看XMLHttpRequest这个对象的属性。
它的属性有:
onreadystatechange 每次状态改变所触发事件的事件处理程序。
responseText 从服务器进程返回数据的字符串形式。
responseXML 从服务器进程返回的DOM兼容的文档数据对象。
status 从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)
status Text 伴随状态码的字符串信息
readyState 对象状态值
0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
1 (初始化) 对象已建立,尚未调用send方法
2 (发送数据) send方法已调用,但是当前的状态及http头未知
3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,
4 (完成) 数据接收完毕,此时可以通过通过responseXml和responseText获取完整的回应数据
如上所示,函数首先检查XMLHttpRequest的整体状态并且保证它已经完成(readyStatus=4),即数据已经发送完毕。然后根据服务器的设定询问请求状态,如果一切已经就绪(status=200),那么就执行下面需要的操作。
对于XmlHttpRequest的两个方法,open和send,其中open方法指定了:
a、向服务器提交数据的类型,即post还是get。
b、请求的url地址和传递的参数。
c、传输方式,false为同步,true为异步。默认为true。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式。
Send方法用来发送请求。
知道了XMLHttpRequest的工作流程,我们可以看出,XMLHttpRequest是完全用来向服务器发出一个请求的,它的作用也局限于此,但它的作用是整个ajax实现的关键,因为ajax无非是两个过程,发出请求和响应请求。并且它完全是一种客户端的技术。而XMLHttpRequest正是处理了服务器端和客户端通信的问题所以才会如此的重要。
现在,对ajax的原理大概可以有一个陈述了:可以把服务器端看成一个数据接口,它返回的是一个纯文本流,当然,这个文本流可以是XML格式,可以是Html,可以是Javascript代码,也可以只是一个字符串。这时候,XMLHttpRequest向服务器端请求这个页面,服务器端将文本的结果写入页面,这和普通的web开发流程是一样的,不同的是,客户端在异步获取这个结果后,不是直接显示在页面,而是先由javascript来处理,然后再显示在页面。至于现在流行的很多ajax控件,比如magicajax等,可以返回DataSet等其它数据类型,只是将这个过程封装了的结果,本质上他们并没有什么太大的区别。
下面是一个后端对ajax进行响应的案例:
@app.route(\'/mystring\')
def mystring():
return \'my
string\'
与其它路由方法没什么不同。
当然,现在一般使用jquery,提供了更好的封装,使用起来也更方便。
5.1. 优缺点及应用场景
优点:
1.使用异步方式与服务器通信,页面不需要重新加载,页面无刷新
2.按需取数据,减少服务器的负担
3.使得Web应用程序更为迅捷地响应用户交互
4.AJAX基于标准化的并被广泛支持的技术,不需要下载浏览器插件或者小程序,但需要客户允许JavaScript在浏览器上执行
5.浏览器的内容和服务端代码进行分离。页面的内容全部由JAVAScript来控制,服务端负责逻辑的校验和从数据库中拿数据。
缺点:
1.安全问题:将服务端的方法暴露出来,黑客可利用这一点进行攻击
2.大量JS代码,容易出错
3.Ajax的无刷新重载,由于页面的变化没有刷新重载那么明显,所以容易给用户带来困扰——用户不太清楚现在的数据是新的还是已经更新过的;现有的解决有:在相关位置提示、数据更新的区域设计得比较明显、数据更新后给用户提示等
4.可能破坏浏览器后退按钮的正常行为;
5.一些手持设备(如手机、PAD等)自带的浏览器现在还不能很好的支持Ajax
应用场景:
1.对数据进行过滤和操纵相关数据的场景
2.添加/删除树节点
3.添加/删除列表中的某一行记录
4.切换下拉列表item
5.注册用户名重名的校验
6. 总结
js是一种脚本语言,每个浏览器都内置了解释器。
flask或者说web服务器不关心网页中js脚本的内容,它被视为网页源码的一部分被发送给浏览器,然后由浏览器进行解释。
ajax是一种依赖于XMLHTTPRequest进行数据交换而无需更新整个网页的技术(废话)。
对于后端而言,ajax是透明的,它不关心,与普通路由没什么区别。
jquery是一个js库,包含一些常用的js函数,它与js的关系类似于urllib之于python。
7. 参考
jquery:http://www.runoob.com/jquery/jquery-tutorial.html
https://www.cnblogs.com/dulmcat/p/5812062.html
https://www.cnblogs.com/wanghp/p/6991554.html
以上是关于flask与javascript及ajax的主要内容,如果未能解决你的问题,请参考以下文章
轻量级NoSQL数据库与PythonWeb-Flask框架组合使用4-项目布局及应用配置
flask-day2——cbv源码分析模版语法请求与响应session及源码分析闪现请求扩展