使用AJAX技术发送异步请求
什么是AJAX
AJAX指一步Javascript和XML(Asynchronous JavaScript And XML),它是一些列技术的组合,简单来讲AJAX基于XMLHttpRequest让咱们在不重载页面的状况下和服务器进行数据交换。javascript
加上JavaScript和DOM(Document Object Model,文档对象模型),咱们就能够在接收到响应数据后局部更新页面。XML指的是数据的交互模式,能够是纯文本(Plain Text)、HTML或JSON。java
使用jQuery发送AJAX请求
jQuery是流行的JavaScript库,它包装了JavaScript,让咱们经过更简单的方式编写JavaScript代码。对于AJAX,它提供了多个相关的方法,使用它能够很方便地实现AJAX操做。更重要的是,jQuery处理了不一样浏览器的AJAX兼容问题,咱们只须要编写一套代码,就能够在全部主流浏览器上运行。jquery
在示例中,使用全局jQuery函数ajax()发送AJAX请求。ajax()函数是底层函数,有丰富的自定义配置,支持的主要参数以下:ajax
jQuery还提供了快捷方法:用户发送GET请求的get()方法和用于发送POST请求的post()方法,还有直接用于获取json数据的getjson()以及获取脚本的getscript()方法。这些方法都是基于ajax()方法实现的。json
返回“局部数据”
对于处理AJAX请求的视图函数来讲,不会返回完整的HTML响应,这时通常会返回局部数据,常见的类型有纯文本或局部HTML模板、JSON数据或者空值windows
下面程序对应的页面中,咱们显示一片很长的虚拟文章,文章正下方有一个”Load More”的按钮,当按钮被单击时,会发送一个AJAX请求获取文章的更多内容并直接动态插入到文章下方。浏览器
用来显示虚拟文章视图是show_post服务器
文章的随机正文经过Jinja2提供的generate_Jorem_ipsum()函数生成,n参数用来指定段落的数量,默认为5,它会返回由随机字符组成的虚拟文章。文章下面添加了一个”Load More”按钮。按钮下面是两个<script></script>代码块,第一个script是从CDN加载jQuery资源。app
在第二个script标签中,咱们在代码的最外层建立了一个$(function(){…})函数,这个函数是常见的$(document).ready(function(){…})函数的简写形式。这个函数用来在页面DOM加载完毕后执行代码,相似传统JavaScript中的window.onload方法,因此咱们一般会将代码包装在这个函数中。美圆符号是jQuery的简写,咱们经过它来调用jQuery提供的多个方法,因此$.ajax()等同于jQuery.ajax()。异步
在$(function(){…})中,$(‘#load’)被称为选择器,咱们在括号中传入目标元素的id、class或是其余属性来定位对应的元素,将其建立为jQuery对象。咱们传入了”Load More”按钮的id值以定位到加载按钮。在这个选择器上,咱们附加了.click(function(){…}),这会为加载按钮注册一个单击事件处理函数,当加载按钮被单击时就会执行单击事件回调函数。在这个回调函数中,咱们使用$.ajax()方法发送一个AJAX请求到服务器,经过url将目标URL设为”/more”,经过type参数将请求的类型设为GET。当请求成功处理并返回2xx响应或304响应,会触发success回调函数。success回调函数接收的第一个参数为服务器端返回的响应主体,在这个回调函数中,咱们在文章正文(经过$(‘.body’)选择)底部使用append()方法插入返回的data数据。
from jinja2.utils import generate_lorem_ipsum
@app.route('/post')
def show_post():
post_body = generate_lorem_ipsum(n=2)#生成两段随机文本
return u'''
<h1>A very long post</h1>
<div class="body">%s</div>
<button id="load"> Load More</button>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function() {
$('#load').click(function() {
$.ajax({
url: '/more', // 目标URL
type: 'get', // 请求方法
success: function(data){ // 返回2XX响应后触发的回调函数
$('.body').append(data); // 将返回的响应插入到页面中
}
})
})
})
</script>''' %post_body
@app.route('/more')
def load_post():
return generate_lorem_ipsum(n=1)
if __name__ == '__main__':
app.run(debug = True)
结果:
访问127.0.0.1:5000/post页面
点击Load More按钮,浏览器会在后台发送一个GET请求到/more,这个视图返回的随机字符会被动态的插入到文章下方
能够看到页面没有刷新,只是在底部多显示了一段内容
再次点击按钮
HTTP服务器端推送
不管是传统的HTTP请求-响应式的通讯模式,仍是一部的AJAX式请求,服务器端始终处于被动的应答状态,只有在客户端发出请求的状况下,服务器端才会返回响应。这种通讯模式被称为客户端拉取。
在某些场景下,须要的通讯模式是服务器端的主动推送。好比一个聊天室有不少用户,当某个用户发送消息后,服务器接收到这个请求,而后把消息推送给聊天室的全部用户。
相似这种关注实时性的状况还有不少,好比社交网站的导航栏实时显示新提醒和私信的数量,用户的在线状态更新,股价行情监控、显示商品库存信息、多人游戏、文档协做等。
实施服务器桂松的一些列技术被合称为HTTP Server push(http服务器端推送),目前经常使用的推送技术以下:
轮询(polling)这类使用AJAX技术模拟服务器端推送的方法实现起来比较简单,但一般会形成服务器资源上的浪费,增长服务器的负担,并且会让用户的设备消耗更多的电量(频繁的发起异步请求)。SSE效率更高,在浏览器的兼容性方面,除了windows IE/Edge,SSE(server-sent event)基本支持全部主流浏览器,但浏览器一般会限制标签页的连接数量。
除了这些推送技术,在HTML5的API中还包含了一个WebSocket协议,和HTTP不一样,它是一种基于TCP协议的全双工通讯协议。和前面说的服务器端推送技术相比,WebSocket实时性更强,并且能够实现双向通讯。另外,WebSocket的浏览器兼容性要强于SSE。