ajax
- 中间件
7.4 检测登录状态中间件
方法: 在每个路由中都要检测 isLogin 的状态,除了 /login 和 /checkLogin
7.5 中间件类别
express有五种类别的中间件:
- 应用级别的中间件: 挂载到 app 上的中间件,例如:app.use()
- 路由级别的中间件: 挂载到 router 对象上的中间件,例如:router.get()、 router.post
- 错误级别的中间件: 回调函数中,有四个参数 app.use((err, req, res, next)=>{})
- 内置中间件: express.static() , express提供的唯一内置中间件
- 第三方中间件: 非express框架提供的,需要程序员手动安装才能使用的中间件;body-parser 解析post 表单数据
Ajax技术-1
每日任务:
知道什么是Ajax
知道XMLHttpRequest核心对象
能够发送Ajax请求并接收返回的数据
知道什么是get缓存
- 案例---新用户注册时用户名冲突问题
1.1 传统模式解决方案
-
在注册页面中输入用户名和密码,点击“注册”时,要将表单数据提交给后台
-
后台PHP页面,接收用户名和密码之后,要去验证用户名是否存在,如果存在则提示用户名存在,再跳转回注册页面,重新输入。
当用户名存在时,提示用户名已被占用,再跳转回登录页
当用户名不存在时,正常注册新用户
1.2 ajax解决方案
当光标离开用户名文本框时,就已经验证了用户名是否存在,并给予提示了。
用户名被占用:
用户名可用 :
1.3 两种模式对比
传统模式:
两个路由:
/register: 用来显示表单页
/checkRegister: 用来检测用户名是否被占用。 如果被占用,则回跳转回/register,要求用户重新填写。
点击 "注册" 按钮时,跳转到 /checkRegister 进行处理
Ajax模式:
两个路由:
/register: 用来显示表单页
/checkUsername: 用来检测用户名是否被占用。无论是否被占用都会返回信息。
重点是该方法没有页面跳转
当用户名文本框失焦时,请求了 /checkUsername, 对用户进行了验证。 能够实现该操作,依靠了Ajax的核心对象 XMLHttpRequest 。
Ajax的优势:没有页面跳转,用户体验提升。
Ajax就是在页面没有刷新或者没有跳转的情况下还能更新页面的某一部分数据
2.ajax快速入门
2.1 ajax概述
- Ajax: Asynchronous javascript and xml (异步javascript和xml)。
- Ajax并不是一种新技术,而是已有技术的集合。JavaScript是核心载体。
- Ajax优势:在不刷新页面的情况下,更新页面数据,提升用户体验。
- Ajax就像一个小秘书,能够实现异步工作。
2.2 发送Ajax请求
2.2.1 ajax核心对象 --- XMLHttpRequest对象
历史:
1999年诞生,微软在IE5中集成了XMLHttpRequest对象,但是并没有受到人们重视。
2005年,google在gtalk即时聊天工具中使用了该对象,从此之后Ajax技术开始受到人们的重视
创建XMLHTTPRequest对象要分为(低版本) IE和非IE两种方式(主流):
IE浏览器(IE7之前) :
var xhr = new ActiveXObject('Msxml2.XMLHTTP');
非IE浏览器(chrome、firefox、safair、搜狗等,包括IE7+之后) (主流浏览器):
var xhr = new XMLHttpRequest();
案例:创建XMLHttpRequest对象,兼容IE7之前和主流浏览器
//创建XMLHttpRequest对象,兼容低版本IE和非IE浏览器
function getXhr () {
var xmlhttp;
if (window.XMLHttpRequest) {
//IE7+ 和 非IE 中都有 XMLHttpRequest对象
xmlhttp = new XMLHttpRequest();
} else {
//低版本IE浏览器 实例化方式
xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
}
return xmlhttp;
}
2.2.2 核心方法
XMLHttpRequest对象有了,可以发送Ajax请求了。发送请求需要两个方法:
open(var1, var2, var3): 准备Ajax请求
var1: 请求方式 get/post
var2: 请求的后端程序地址,可以是php,jsp,asp,nodejs
var3: 异步(true)/同步(false),可选参数,默认为true
示例: xhr.open(‘get’, ‘/checkLogin’); //准备以get方式请求后端的/checkLogin 路由
send([var]): 发送Ajax请求
var: 分为两种情况。 如果是get请求,则填写null 或者不填。 如果是post请求,则填写要发送到后端的数据。
2.2.3 发送请求案例
在index.html页面上创建按钮,点击该按钮时使用get方式请求后端的 /checkLogin
发送Ajax请求流程:
-
创建XMLHttpRequest对象
-
调用open方法准备ajax请求
-
调用send方法发送ajax请求
代码实现:
-
先创建 app.js 和 index.html ,显示index.htm页面
-
在 index.html 页面通过点击事件发送Ajax请求,请求后端 /checkLogin
① 获取按钮,注册点击事件
② 事件函数 --- 发送Ajax请求
i. 创建 xhr 对象
ii. 调用open方法准备请求
iii. 调用send方法发送请求
2.3 接收后端响应结果
2.3.1 核心属性 --- readyState
Ajax的整个过程有5个状态,对应readyState的5个值:0-4
《Pragmatic Ajax A Web 2.0 Primer 》 中对readyStae状态的介绍
0: (Uninitialized) the send( ) method has not yet been invoked.
1: (Loading) the send( ) method has been invoked, request in progress.
2: (Loaded) the send( ) method has completed, entire response received.
3: (Interactive) the response is being parsed.
4: (Completed) the response has been parsed, is ready for harvesting.
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
百度百科:
0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
1 (初始化) 已调用send()方法,正在发送请求
2 (发送数据) send方法调用完成,但是当前的状态及http头未知
3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,
4 (完成) 数据接收完毕,此时可以通过responseBody和responseText获取完整的回应数据
最核心的重点: 4 , 后端返回的数据已经可以在浏览器中使用了。
2.3.2 核心事件 --- onreadystatechange
onreadystatechange事件: readyState的值每次发生变化都会触发该事件。
0-->1 1-->2 2-->3 3-->4 总共触发4次
2.3.3 其他重要属性
responseText:以字符串形式接收后端程序的返回值。
responseXML:以XML格式接收后端程序返回值
2.3.4 响应案例
-
在 app.js 中创建 /checkLogin 路由监听,使用 res.send 返回一个字符串
-
在 index.html 中使用 readyState、onreadystatechange、responseText 配合接收 /check 返回的数据
代码实现:
-
在 app.js 中创建 /checkLogin 路由监听,使用 res.send 返回一个字符串
-
在 index.html 中使用 readyState、onreadystatechange、responseText 配合接收 /check 返回的数据
测试结果:
2.4 Ajax程序总结
编写一个Ajax程序我们需要监听两个url, 三个步骤
一个url用来显示html页面,在该页面上使用某种事件来触发Ajax请求
一个url用来接收Ajax请求,进行处理后将结果返回给浏览器。返回的结果一般是 字符串 或者 json
三个步骤:
-
第一步: 在页面上使用某种事件触发Ajax请求 (index.html 中黄色区域)
-
第二步: 在后端处理请求,并返回结果给前端 ( 右边绿色区域 )
-
第三步: 前端接收后端返回结果,再进一步处理 (index.html 中灰色区域)
2.5 综合案例
点击按钮,从student表中随机取出一条学生信息,显示在网页上。
思路分析:
思路分析:
-
创建 app.js,创建服务器并启动。再显示index.html 页面
-
在 index.html 页面,添加按钮,注册点击事件,发送Ajax请求
-
编写后端 /getData, 查询student表,获取数据,并拼接成字符串返回给前端
-
index.html 页面使用onreadystatechange、readyState、responseText 接收返回的数据,并显示在浏览器上
代码实现:
-
创建 app.js,创建服务器并启动。再显示index.html 页面
-
在 index.html 页面,添加按钮,注册点击事件,发送Ajax请求
-
编写后端 /getData, 查询student表,获取数据,并拼接成字符串返回给前端
-
index.html 页面使用onreadystatechange、readyState、responseText 接收返回的数据,并显示在浏览器上
测试结果:
- POST和GET
3.1 GET方式实现新用户注册---用户名检测
思路分析:
-
用户名文本框上注册失焦事件。
事件函数: 获取已经填好的用户名,并发送Ajax请求,同时将用户名一起发送给后端(/checkUsername)
-
/checkUsername:
① 接收用户名
② 编写SQL语句。 核心: select * from users where user_name=?
如果查询结果是一条数据,说明用户名已经被占用;如果查询结果是0条数据,说明用户名未占用
③ 执行SQL语句
④ 处理SQL执行结果 ---> 将验证结果返回给前端
-
register.html 接收后端返回的结果,显示在用户名文本框的后面
代码实现:
创建 app.js 显示 register.html 页面
-
用户名文本框上注册失焦事件。
事件函数: 获取已经填好的用户名,并发送Ajax请求,同时将用户名一起发送给后端(/checkUsername)
-
/checkUsername:
① 接收用户名
② 编写SQL语句。 核心: select * from users where user_name=?
如果查询结果是一条数据,说明用户名已经被占用;如果查询结果是0条数据,说明用户名未占用
③ 执行SQL语句
④ 处理SQL执行结果 ---> 将验证结果返回给前端
-
register.html 接收后端返回的结果,显示在用户名文本框的后面
核心: get方式传参就是使用 ?key=value 的形式将数据链接在路由后面
3.2 POST方式实现新用户注册---用户名检测
post和get两种方式的整体思路一致,只是细节上有所差别
-
使用open准备请求时,参数1需要设置为post,参数2只需要设置后端程序地址。
-
将需要传递到后端的数据拼接成一个独立的字符串,字符串的格式为
var str = ‘key=value&key=value&....’; (内部结构跟get传参时的结构一致)
-
调用setRequestHeader方法将数据格式转为 application/x-www-form-urlencoded
-
将拼接好的数据字符串作为参数传入send方法
-
后端接收时使用 body-parser 模块接收(req.body)
代码实现:
-
前端使用post方式发送Ajax请求,并传递数据
-
后端使用 body-parser 模块接收,然后验证
关键点总结:
-
发送程序时,参数1设置为post,参数2只用设置请求的后端文件路径
xhr.open('post', 'post.php');
-
将需要传递到后端的数据拼接成一个独立的字符串
var str = 'name='+name;
-
调用setRequestHeader方法将数据格式转为 application/x-www-form-urlencoded
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
-
发送请求时,要将之前拼接好的字符串作为参数放入send方法中
xhr.send(str);
- GET缓存
4.1 什么是缓存?
浏览器的请求需要从服务器获得许多 css、img、js 等相关的文件,如果每次请求都把相关的资源文件加载一次,对 带宽、服务器资源、用户等待时间 都有严重的损耗。如果浏览器将css、img、js等文件在第一次请求成功后就保存在本机上,以后的每次请求就在本机获得相关的资源文件,那么就可以明显地加快用户的访问速度,同时可以节省各种资源(带宽、服务器资源、用户等待时间)。
4.2 GET缓存测试
ajax方式,get会有缓存问题。
案例:
index.html页面中创建一个按钮,点击该按钮时发送ajax请求,得到后端php程序返回的当前时间戳并显示。
-
index.html 发送Ajax请求
-
后端使用moment模块获取当前时间并返回给前端
使用IE浏览器测试:
连续测试会发现永远是这个时间,说明被缓存了。
4.3 解决方法
在open准备ajax请求时,为请求的地址增加随机后缀。相当于每次请求都是新的地址
随机后缀一般是 随机数或者时间戳

浙公网安备 33010602011771号