Ajax-day01
相关概念
关于网站
什么是网站?
- 能够通过网站查看网页,通过网页可以浏览器信息,发布微博、博客、评论、购物
 - 从程序员角度,网站其实就是一堆网页
 - 网页由什么组成?HTML、CSS、javascript
 
程序员开发的网站如何才可以被被人看到呢?
- 需要把网站的代码放到【服务器】上,然后别人就可以通过网址访问网站页面了
 
什么是服务器?
- 其实就是一台计算机(一般在机房中放着)
 - 用于提供服务(提供网站服务)
 
客户端-服务器交互模型
网站开发好之后,需要上线(把代码上传到服务器上),客户端(浏览器)需要通过请求的方式访问服务器中的网页,服务器收到请求后,把网页返回给浏览器,然后浏览器把页面呈现出来。
- 客户端(浏览器)发送请求到服务器
 - 服务器返回网页给浏览器用于展示
 

总结
客户端主动向服务器发送请求,服务器返回网页,浏览器再展示——-客户端/服务器交互模型
URL地址格式
URL地址的作用:可以唯一标识服务器中的某个资源(网页等内容)
- URL(uniform resource locator 统一资源定位符)地址一般由三部组成:
① 协议:客户端与服务器之间的通信协议(约定计算机之间的通信规则)
② 服务器名称:存有该资源的服务器名称,通过它可以找到互联网中对应得那台计算机
③ 路径:资源在服务器上具体的存放位置:告诉客户端文件的位置 
总结:
- URL作用:用于区分互联网中的一个资源(网页)
 - 熟悉URL的基本组成
 
服务端资源类型
- 服务器中所有的可以通过URL地址访问的内容都称之为【资源】
 - 每一个URL地址都对应服务器中的一个资源
 网页内部资源的组成
- html标签 .html
 - css样式 .css
 - js代码 .js
 - 图片 .png/.gif…..
 - 字体图标 .svg/….
 - 音频 .mp3
 - 视频 .mp4
 - 数据(重中之重)
 - ……
 
总结:
网页可能由很多资源组成,这些资源包括:html/css/js/图片。。。。
其中最重要的是数据资源,这种资源后续是重中之重。
浏览器调试工具基本用法
通过浏览器调试工具查看请求响应过程
- 网页中右键—>检查
 - 快捷键 F12(ctrl + shift + i)
 
页面中的相关资源查看方式
- All 表示全部类型资源
 - XHR Ajax请求的资源(重中之重)
 - img 图片资源
 - js js文件链接资源
 - css css文件链接资源
 - Doc 表示网页本身的文件资源
 

总结:借助浏览器的调试工具,可以直观的看到浏览器发送的请求到底返回了什么
Ajax概述
Ajax:Asynchronous Javascript And Xml (异步 JavaScript 和 XML)
Ajax可以解决什么问题
- 传统的网站访问方式:客户端发送请求,服务器返回网页,浏览器展示网页
 - 如果长时间服务器没有返回内容,浏览器只能等待(阻塞:白屏),用户体验较差
 - 为了解决这个问题,就诞生了Ajax
 - Ajax发送请求时,可以不阻塞浏览器,那么浏览器就不会白屏,体验会变好。
 
Ajax是什么
- Ajax是一种改善浏览网页用户体验的一种技术,通过不阻塞(异步)浏览器发送请求的这种方式改善体验。
 
Ajax应用场景
- 用户名服务端验证
 

- 搜索智能提示
 

- 数据分页显示
 

总结:
通过Ajax可以实现页面的局部更新(传统的方式是整页刷新)
基于jQuery的Ajax用法
原生js提供了XMLHttpRequest用于实现Ajax,用法比较繁琐,后续再做分析,先基于jQuery方法实现Ajax
发送GET请求
- $.get方法,主要用于向服务器查询资源
 
// 需求:点击按钮发送请求到服务器,获取服务器返回的资源,然后更新页面$('#btn').click(function () {// 1、发送一个请求给服务器// $.get的方法参数// 参数一表示请求的url地址// 参数二表示回调函数,后端返回数据后自动触发,通过形参获取服务器返回的结果$.get('http://www.liulongbin.top:3006/api/getbooks', function (result) {// 2、把返回的数据展示到页面$('#result').html(result.msg)})})
- $.get请求传递请求参数
 
{id: 1} 参数实际上最终携带到URL地址中进行请求发送
// get 请求如何传递参数// 1、给按钮绑定单击事件$('#btn').click(function () {// 发送get请求时如何传递参数(查询条件)$('#btn').click(function () {// 1、发送一个请求给服务器// $.get的方法参数// 参数一表示请求的url地址// 参数二表示回调函数,后端返回数据后自动触发,通过形参获取服务器返回的结果// url地址中?之后的内容称之为查询字符串// 查询字符串的格式 ?key1=value1&key2=value2$.get('http://www.liulongbin.top:3006/api/getbooks?id=74&author=1', function (result) {// 2、把返回的数据展示到页面$('#result').html(result.msg)})})// ------------------------------------------------var id = 74var author = 1/*参数一:表示请求的url地址参数二:表示请求的get参数参数三:表示服务器返回成功的回调函数*/$.get('http://www.liulongbin.top:3006/api/getbooks', {id: id,author: author},function (result) {// 2、把返回的数据展示到页面$('#result').html(result.msg)})})
总结:
- $.get方式发送请求的主要目的,为了查询服务器的数据
 查询数据时可以传递参数
- 自己拼接字符串方式,接到url地址?之后
 - 基于$.get方法的参数二传递,参数类型是对象
 注意:?之后的那部分参数内容称之为【查询字符串(请求参数)】
发送POST请求
刚才是为了查询数据;还有一种场景是为了向后端提交数据(发微博;注册用户。。。)
post请求的主要目的就是提交数据给服务器
post 提交的参数不会添加到url地址中,而是以【请求体】方式提交

// 发送post请求时如何传递参数(查询条件)$('#btn').click(function () {// 添加图书/*参数一表示请求的url地址参数二表示请求参数(提交给服务器的数据)参数三表示提交成功的回调*/$.post('http://www.liulongbin.top:3006/api/addbook', {author: '施耐庵',bookname: '水浒传',publisher: '出版社'}, function (result) {$('#result').html(result.msg)})})
总结:
- post请求的目的是为了向服务器提交数据
 - 通过$.post方法的参数二进行提交数据
 - post提交的数据不可以在url地址中看到,但是在Headers的最底部可以看到(请求体)
 
$.ajax方法用法
$.ajax方法
- type 请求方式 (GET 和 POST),不区分大小写
 - url 请求地址
 - data 请求参数
 - success 服务器返回数据成功的回调函数
 
// 需求:通过$.ajax方法发送请求// 1、给按钮绑定单击事件$('#btn').click(function () {// 向服务器发送请求$.ajax({// 请求方式type: 'get',// 请求url地址url: 'http://www.liulongbin.top:3006/api/getbooks',// 传递参数// data: {// id: 1,// autor: '吴承恩'// },// 成功获取服务器端返回数据的回调函数success: function (res) {$('#result').html(res.data.length)}})// -------------------------------------// $.ajax({// // 请求方式// type: 'post',// // 请求url地址// url: 'http://www.liulongbin.top:3006/api/addbook',// // 传递参数// data: {// author: '吴军',// bookname: '浪潮之巅',// publisher: '出版社'// },// // 成功获取服务器端返回数据的回调函数// success: function (res) {// $('#result').html(res.msg)// }// })})
总结
- $.ajax既可以发送get请求,也可以发送post请求
 $.ajax 两者皆可
- $.get 专门用于发送get请求
 - $.post 专门用于发送post请求
 
GET和POST的区别
get主要目的获取服务器的资源,可以传递参数(作为查询条件)
- get请求参数需要用url地址进行传递(?之后的查询字符串 key=value&key1=value1)
 - get请求传参有限制:8000个字符
 
post主要目的向服务器提交数据
- post请求参数以请求体方式进行传递,不会添加到URL地址
 - 如果要提交的数据量比较大,需要使用post
 
总结:
- get主要目的是查询数据,但是url地址传递的数据量有限制
 - post主要目的是提交数据,具体提交的数据量由后端决定,一般是几M(对于提交表单来说,完全够用)
 - 实际上,前端发送请求时,用get或者post谁说了算?后端
 
总结
相关概念
- 网站和服务器
 - 客户端服务器交互模型
 - 客户端通过url地址发送请求
 - url地址和服务器中的资源是一一对应的
 - 一个网页中包含很多资源:资源有很多类型html/css/js/图片。。。。
 - 通过浏览器的调试工具的netWord选项可以直观的看到这些资源
 - 这些资源中重中之重是数据
 
Ajax介绍
- 传统的网页访问方式问题:导致浏览器阻塞(白屏)
 - 为了改善这种体验,就诞生了Ajax
 - Ajax是一种技术(局部更新:底层用的异步请求)
 Ajax的应用场景
- 注册时账号的重复性验证
 - 搜索的职能提示
 - 表格分页效果
 
基于jQuery的Ajax用法
- $.get发送get请求并且可以传递参数
 - $.post发送post请求参数
 - $.ajax支持上述两种请求方式
 - get和post请求方式的区别
 
问题分析
为什么A地址添加的数据B地址可以查询出来?

总结:
- 添加图书时,请求后端URL地址并且传递参数,后端负责把数据存入数据库
 - 查询图书时,请求后端URL地址并且传递参数,后端负责根据参数查询数据库并返回
 注意:数据库都是共享的
后端接口
关于接口
- 什么是接口?两种东西对接的方式
 - Ajax中提到的接口指的是什么?URL地址(前端和后端的对接)
 URL地址是由后端规定的,除了URL还需求更多的信息描述接口,具体来说需要什么呢?
- 接口的基本的功能描述
 - 请求路径 /api/getbooks
 - 请求方式 GET/POST
 - 请求参数(前端传递给后端的参数)
 - 响应结果(服务器返回的数据)
 
接口文档
接口:对于Ajax来说,我们提到的接口指的是URL地址
接口核心信息(需要描述接口的功能)
- 请求地址:URL地址
 - 请求方式:GET 和 POST
 - 请求参数:get方式通过URL传参;post方式通过请求体传参
 - 响应结果数据:服务端返回的数据
 
需要专门提供一个接口文档描述每一个接口的详细信息,有了接口文档,前端就可以调用该接口了。
接口文档一般由后端提供,主要描述接口的相关信息,供前端使用
接口调试工具
通过工具测试后端的接口是否正常,不需要写代码 Postman
- 测试get请求
 

- 测试post请求
 

总结:
- Postman工具的作用:不写代码证明后端提供的接口是否正常
 - 如何测试get请求和post请求
 
Ajax具体做了什么?通过Ajax向后端发送请求,获取后端返回的资源(数据)
如果我们不用Ajax,那么可以用何种方式向后端发送请求?直接通过浏览器地址栏发送请求;点击链接也是,这些方式发送请求时。需要整页刷新,并且如果请求发出后,尚未返回内容时,浏览器是阻塞的(白屏)
我们为什么要使用Ajax向后端发送请求?提升用户体验,不让浏览器阻塞(没有白屏)
如何用Ajax发送请求?
- 原生Ajax(繁琐)
 - jQuery的Ajax(简单)
 
如何用jQuery相关的方法发送请求?
- $.get
 - $.post
 - $.ajax
 
我们如何知道调用哪个接口?后端需要提供一份接口文档
这个接口文档需要描述什么信息?
- 基本功能说明
 - 请求地址
 - 请求方式
 - 请求参数
 - 响应结果
 
图书管理案例
目标:实现图书管理列表展示,添加图书、删除图书功能(界面布局采用Bootstrap)
这个功能效果用于什么场景?图书管理

页面基本布局
- 顶部添加图书表单
 - 底部图书列表表格
 
<!-- 添加图书的Panel面板 --><div class="panel panel-primary"><div class="panel-heading"><h3 class="panel-title">添加新图书</h3></div><div class="panel-body form-inline"><!-- 表单输入域 --><div class="input-group"><div class="input-group-addon">书名</div><input type="text" class="form-control" id="iptBookname" placeholder="请输入书名"></div></div></div><!-- 图书的表格 --><table class="table table-bordered table-hover"></table>
获取图书列表数据
页面加载时调用接口获取图书列表数据
- 接口路径:api/getbooks
 
// 获取图书列表数据并进行展示function queryData () {$.get('http://www.liulongbin.top:3006/api/getbooks', function (res) {// 把后端获取的数据填充到表格中if (res.status === 200) {var books = res.data}})}queryData()
列表数据渲染
把数据动态填充到HTML标签的过程:前端渲染
- 通过字符串拼接渲染图书列表数据
 
var arr = res.datavar tags = ''for (var i = 0; i < arr.length; i++) {var book = arr[i]tags += '<tr><td>'+book.id+'</td><td>'+book.bookname+'</td><td>'+book.author+'</td><td>'+book.publisher+'</td><td>删除</td></tr>'}
- 基于ES6的模板字符串方式
 
// 把数据填充到标签中(前端渲染)var trTags = ''// 遍历数据进行字符串拼接res.data.forEach(function (item) {// 拼接其中一行数据trTags += `<tr><td>${item.id}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td><a href="">删除</a></td></tr>`})// 把tr所以行拼接的字符串追加到页面$('tbody').html(trTags)
总结:
- 实现前端基本静态布局
 - 调用接口获取后端的图书列表数据
 - 把列表数据动态填充到HTML标签中
 
添加图书
- 提交表单事件处理
 - 获取表单数据
 - 调用接口添加图书
 - 服务器返回一个添加成功的状态
 - 客户端判断状态并且刷新列表并且清空表单
 
// 功能2:添加图书// 1、绑定表单的提交事件$('#btnAdd').click(function () {// 2、获取表单的数据let bookname = $('#iptBookname').val()let author = $('#iptAuthor').val()let publisher = $('#iptPublisher').val()// 3、调用接口添加图书$.post('http://www.liulongbin.top:3006/api/addbook', {bookname: bookname,author: author,publisher: publisher}, function (result) {// 4、判断是否成功if (result.status === 201) {// 添加成功// 5、刷新列表(局部刷新)loadBookList()// 6、清空表单$('#iptBookname').val('')$('#iptAuthor').val('')$('#iptPublisher').val('')} else {// 添加失败alert(result.msg)}})})
- 表单验证
 
// 获取表单数据var bookname = $('#bookname').val()var author = $('#author').val()var publisher = $('#publisher').val()// 表单验证if (!bookname) {alert('图书名称不能为空')// 阻止后续代码的执行return}if (!author) {alert('图书作者不能为空')// 阻止后续代码的执行return}if (!publisher) {alert('出版社不能为空')// 阻止后续代码的执行return}
总结:
- 表单验证的作用:检查数据的合法性,如果数据不合法,应该禁止调用接口
 - 即使前端做了验证,后端也会再次进行验证
 
删除图书
删除图书按钮事件处理
- 通过事件委托方式绑定事件
 - (‘tbody’).on(‘click’, ‘a’, function () {})
 
根据图书ID调用后台接口删除图书
- 删除图书接口路径 api/delbook
 
// 功能3:删除图书// 1、绑定删除图书的事件$('#tb').on('click', '.del', function () {// 如何判断删除的是谁?获取图书的id// 获取标签的自定义属性的值 $(this).data('id') 或者 $(this).attr('data-id')const id = $(this).data('id')// 2、确认要删除吗const flag = confirm('确认要删除吗?')if (flag) {// 点击了确认按钮// 3、调用接口删除图书$.get('http://www.liulongbin.top:3006/api/delbook', {id: id}, function (result) {if (result.status === 200) {// 删除成功,刷新列表// 4、刷新页面loadBookList()}})}})
总结:
- 删除操作一般要添加确认
 - 熟悉事件委托写法
 - 自定义属性的用法
 $('a').data('id')
- 我们前端没有写删除图书的逻辑代码,为何删除了图书?
 
结论:前端通过调用接口,告诉后端删除数据库中id对应的图书
删除成功后,前端再调用接口查询数据库中剩余的数据,把页面中之前的列表覆盖
回顾
Ajax前置相关概念
- 我们前端开发的网页放到服务器上才可以被别人通过URL地址看到
 - 服务器本质上也是一台计算机,个头更大,性能更高
 - URL用于唯一标识服务器中的资源
 - 资源包括HTML、css,js,图片。。。。
 - 尤其重要的一种资源:数据
 - 客户端-服务器交互模型
 
Ajax概述
- 传统的网页请求响应流程是阻塞的,浏览器出现长时间白屏,用户体验较差
 - 为了改善这种体验,就诞生了Ajax(Gmail、谷歌地球)
 - Ajax是一种改善网页加载体验的一种技术(通过”异步“请求不阻塞浏览器并且进行局部更新)
 
Ajax的基本用法(如何使用Ajax发送请求)
- $.get
 - $.post
 - $.ajax
 get和post的区别
- get主要用于查询数据
 - post主要用于提交数据
 
- 关于接口:前端和后端对接的方式(url地址)
 - 前端怎么知道开发功能是调用哪一个接口?看接口文档
 看文档的那些信息?
- 接口路由
 - 请求方式
 - 请求参数
 - 返回结果
 
图书管理案例
- 图书列表的展示
 - 添加图书
 - 删除图书
 
前端对接后端的流程
- 处理前端事件监听
 - 调用后端接口并获取返回结果
 处理接口返回的结果
- 查询(客户端渲染:把数据拼接到HTML标签里面)
 - 增删改(判断操作成功与否的状态,从而进行后续操作)
 
聊天机器人案例
需求:1、发送消息给接口,接口返回文本内容;2、把文本内容转换成语音并播放
- 聊天机器人效果图如下
 
页面基本布局分析
<div class="wrap"><!-- 头部 Header 区域 --><div class="header"><h3>小思同学</h3><img src="img/person01.png" alt="icon" /></div><!-- 中间 聊天内容区域 --><div class="main"><ul class="talk_list" style="top: 0px;" id="talk_list"><li class="left_word"><img src="img/person01.png" /> <span>嗨,最近想我没有?</span></li></ul><div class="drag_bar" style="display: none;"><div class="drager ui-draggable ui-draggable-handle" style="display: none; height: 412.628px;"></div></div></div><!-- 底部 消息编辑区域 --><div class="footer"><img src="img/person02.png" alt="icon" /><input type="text" placeholder="说的什么吧..." class="input_txt" id="ipt" /><input type="button" value="发 送" class="input_sub" id="btnSend" /></div></div>
- 顶部标题
 - 中间的消息列表
 - 底部的发送消息文本框和按钮
 
发送消息
控制消息发送
- 发送按钮事件绑定
 - 将表单消息添加到消息列表中
 
// 1、绑定发送按钮的点击事件$('#btnSend').click(function () {// 2、点击之后,需要把输入的内容放到中间的列表的右侧const msg = $('#ipt').val()const msgTag = `<li class="right_word"><img src="img/person02.png" /> <span>${msg}</span></li>`$('#talk_list').append(msgTag)// 3、调用接口把输入的文本传递给后端接口$.get('http://www.liulongbin.top:3006/api/robot', {spoken: msg}, function (ret) {const retMsg = ret.data.info.textconsole.log(retMsg)})})
- 滚动条处理
 
// 初始化右侧滚动条,这个方法定义在scroll.js中resetui()
总结:监听事件、获取输入的文本并展示到右侧列表中,处理滚动条
获取聊天机器人消息
- 输入消息后将消息发送给服务器并获取返回的消息
 - 将返回的消息添加到消息列表中
 
// 3、调用接口把输入的文本传递给后端接口$.get('http://www.liulongbin.top:3006/api/robot', {spoken: msg}, function (ret) {const retMsg = ret.data.info.text// 4、接收服务器返回的文本,并且显示到中间列表的左侧const retMsgTag = `<li class="left_word"><img src="img/person01.png" /> <span>${retMsg}</span></li>`$('#talk_list').append(retMsgTag)// 处理滚动条resetui()})
总结:调用接口;获取返回结果;展示左侧列表消息;重置滚动条
将机器人消息转换为语音
- 调用接口实现语音转换
 
// 5、再次调用一个接口把回复的文本传递给服务器$.get('http://www.liulongbin.top:3006/api/synthesize', {text: retMsg}, function (retVoice) {// 6、服务器返回文本转换之后的语音数据(语音的url地址)const voice = retVoice.voiceUrl// 7、利用audio标签把语音播放出来$('#voice').attr('src', voice)})
- 控制声音播放
 
<audio src="" id="voice" autoplay style="display: none;"></audio>
总结:调用接口;获取语音数据并且设置audio标签的src属性播放语音
控制回车键发送消息
监听回车键
- e.keyCode
 
// 为文本框绑定 keyup 事件$('#ipt').on('keyup', function (e) {// console.log(e.keyCode)if (e.keyCode === 13) {// console.log('用户弹起了回车键')// $('#btnSend').click()$('#btnSend').trigger('click')}})
总结
- 键盘间接必须绑定到输入框上,不可以绑定到按钮上
 - 熟悉键盘码 e.keyCode 的用法
 - 手动触发一个事件的用法
 
