AJAX
- 背景环境
- 传统网站存在问题(用户体验不好)
- 网速慢的情况下,页面加载时间长,用户只能等待
- 表单提交后,如果一项内容不合格,需要重新填写所有表单内容
- 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间
- 传统网站存在问题(用户体验不好)
- 概述
- 它是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高用户浏览网站应用的体验
- 应用场景
- 页面上拉加载更多数据
- 列表数据无刷新分页
- 表单项离开焦点数据验证
- 搜索框提示文字下拉列表
- 运行环境
- 网站环境
- 运行原理
- Ajax 相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验
- 实现步骤
- 创建ajax对象
var xhr = new XMLHttpRequest(); - 告诉Ajax请求地址以及请求方式
xhr.open('get', 'http://www.example.com') - 发送请求
xhr.send(); - 获取服务器给与客户端的响应数据
xhr.onload = function () {console.log(xhr.responseText);} - 服务端响应的数据格式
- 真实的项目中,服务器端大多数情况下会以 JSON对象作为响应数据的格式
- 在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输
- JSON.parse() // 将 json 字符串转换为json对象
- 请求参数传递
- get请求方式
- xhr.open('get', 'http://www.example.com?name=zhangsan&age=20')
- post请求方式
xhr.setRequestHeader('Content‐Type', 'application/x‐www‐form‐urlencoded')xhr.send('name=zhangsan&age=20'); - 请求报文
- 在 HTTP 请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,这些数据和信息要遵守规定好的格式
- 请求参数的格式
- application/x-www-form-urlencoded
name=zhangsan&age=20&sex=男 - application/json
{name: 'zhangsan', age: '20', sex: '男'} - 在请求头中指定Content-type属性的值是aplication/json,告诉服务器端
JSON.stringify() // 将json对象转换为json字符串 - get 请求是不能提交 json 对象数据格式的,传统网站的表单提交也是不支持 json 对象数据格式的
- application/x-www-form-urlencoded
- Ajax状态码
0:请求未初始化(还没有调用open())1:请求已经建立,但是还没有发送(还没有调用send())2:请求已经发送3:请求正在处理中,通常响应中已经有部分数据可以用了4:响应已经完成,可以获取并使用服务器的响应了xhr.readyState // 获取Ajax 状态码 - onreadystatechange 事件
// 当Ajax状态码发生变化时xhr.onreadystatechange = function () {// 判断当Ajax状态码为4时if (xhr.readyState == 4) {// 获取服务器端的响应数据console.log(xhr.responseText);}} - 兼容ie低版本
- 需要判断Ajax状态码
- 被调用多次
- onload
- 不兼容ie低版本
- 不需要判断Ajax状态码
- 只被调用一次
- Ajax错误处理问题
- 网络畅通,服务器端能接收到请求,服务器端返回的结果不是预期结果
- 可以判断服务器端返回的状态码,分别进行处理。xhr.status 获取http状态码
- . 网络畅通,服务器端没有接收到请求,返回404状态码
- 检查请求地址是否错误
- .网络畅通,服务器端能接收到请求,服务器端返回500状态码
- 服务器端错误,找后端程序员进行沟通
- 网络中断,请求无法发送到服务器端
- 会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理
- 网络畅通,服务器端能接收到请求,服务器端返回的结果不是预期结果
- 低版本IE浏览器的缓存问题(向同一地址发送多次请求)
- 在请求地址的后面加请求参数,保证每一次请求中的请求参数的值不相同
xhr.open('get', 'http://www.example.com?t=' + Math.random()); xhr.open('get', 'http://www.example.com?t=' + new Date());
- 在请求地址的后面加请求参数,保证每一次请求中的请求参数的值不相同
- get请求方式
- 创建ajax对象
- Ajax异步编程
- Ajax封装
- 模板引擎
- 使用模板引擎提供的模板语法,可以将数据和HTML拼接起来
- 下载 art-template 模板引擎库文件并在 HTML 页面中引入库文件
<script src="./js/template‐web.js"></script> - 准备 art-template 模板
<script id="tpl" type="text/html"><div class="box"></div></script> - 告诉模板引擎将哪一个模板和哪个数据进行拼接
var html = template('tpl', {username: 'zhangsan', age: '20'}); - 将拼接好的html字符串添加到页面中
document.getElementById('container').innerHTML = html; - 通过模板语法告诉模板引擎,数据和html字符串要如何拼接`
<script id="tpl" type="text/html"><div class="box"> {{ username }} </div></script>
- 模板引擎
- formData对象
- 获取表单对象
var form =document.queryselector('form') - 将表单对象转换成formData对象
var formData=new FormData(form); - 提交表单对象
xhr.send(formData) - 获取表单对象中属性的值
formData.get('key'); - 设置表单对象中属性的值
formData.set('key', 'value'); - 删除表单对象中属性的值
formData.delete('key'); - 向表单对象中追加属性值
formData.append('key', 'value'); - set 方法与 append 方法的区别是,在属性名已存在的情况下,set 会覆盖已有键名的值,append会保留两个值。
- 获取表单对象
- Ajax封装
- json
- 用于数据交换的字符串,将对象或者数组序列化后的字符串,json字符串
- JSON.Stringify()将对应的值转换为原始值
- 同源政策
- 为了保证用户信息的安全,放置恶意的网站窃取数据
- 同源:协议+域名+端口号
- 浏览器拒绝处理ajax请求响应回来的数据
- JSONP
- 动态创建script,将请求地址放置在script的src属性上
- 绕过浏览器的同源策略
- 客户端
- 定义一个全局变量
- 将请求地址放置在script的src属性上,并携带一个参数(函数的名字)
- 服务端
- 返回(一段调用的函数的js代码)字符串
- 封装
function JSONP(options) { // 创建script标签 var script = document.createElement('script') var params='' for (var attr in options.data) { params += '&' + attr + '=' + options.data[attr]; } var fnName='jsonp'+Math.random().toString().replace(".",""); window[fnName]=options.success; // 设置src属性 script.src = options.url+'?callback='+fnName+params // 动态添加script标签 document.body.appendChild(script); // 加载完成后删除scrip t script.addEventListener('load', function () { document.body.removeChild(script); })} - 缺点
- 只能发送get请求
- 请求地址
- 请求方式
- 请求参数
- 返回值
- CORS(cross-origin resource sharing)跨域资源共享(不适用于跨域服务器不属于自己)
- 允许服务器向跨域服务器发送Ajax请求(跨域服务器设置一个响应报文)
app.use((req, res, next) => {res.header('Access‐Control‐Allow‐Origin', '*');res.header('Access‐Control‐Allow‐Methods', 'GET, POST');next();})
- 允许服务器向跨域服务器发送Ajax请求(跨域服务器设置一个响应报文)
- 代理(代理处理)
- 向自己服务器发送请求
- 通过自己的服务器向跨域服务器发送请求
- 将响应数据响应给客户端
- $ajax ({
type: 'get',url: 'http://www.example.com',data: { name: 'zhangsan', age: '20' },contentType: 'application/x‐www‐form‐urlencoded',beforeSend: function () {return false},success: function (response) {},error: function (xhr) {}}); 当contentType为 'application/x‐www‐form‐urlencoded',时data为对象或者拼接字符串当contentType为 'application/json',时data使用json.stringify转为字符串传输到服务端都是字符串返回的都是对象- serialize方法
- 将表单中的数据自动拼接成字符串类型的参数
var params = $('#form').serialize();
- 将表单中的数据自动拼接成字符串类型的参数
- 发送jsonp请求
$.ajax({url: 'http://www.example.com',// 指定当前发送jsonp请求dataType: 'jsonp',// 修改callback参数名称//jsonp: 'cb',// 指定函数名称jsonCallback: 'fnName',success: function (response) {}}) - $.get
$.get('http://www.example.com', {name: 'zhangsan', age: 30}, function (response) {}) - $.post
$.post('http://www.example.com', {name: 'lisi', age: 22}, function (response) {})
- serialize方法