Ajax从零入门到精通

在这里插入图片描述Ajax从零入门到精通_第1张图片phpstydy软件下载→启动aphache\mysql→打开根目录 将www下文件删掉 → 将想要的网站复制进去 → 获取本地ip地址(cmd→ipconfig)→打开网站

一、Ajax 编程基础

1、Ajax 基础

传统网站中存在的问题

  • 网速慢的情况下,页面加载时间长,用户只能等待
  • 表单提交后,如果一项内容不合格,需要重新填写所有表单内容
  • 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间

Ajax 概述

Ajax:标准读音 [ˈeɪˌdʒæks] ,中文音译:阿贾克斯
它是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高用户浏览网站应用的体验。

Ajax 的应用场景

  1. 页面上拉加载更多数据
  2. 列表数据无刷新分页
  3. 表单项离开焦点数据验证
  4. 搜索框提示文字下拉列表
    Ajax从零入门到精通_第2张图片Ajax从零入门到精通_第3张图片Ajax从零入门到精通_第4张图片

Ajax 的运行环境

Ajax 技术需要运行在网站环境中才能生效,当前课程会使用Node创建的服务器作为网站服务器。

2、Ajax 运行原理及实现

Ajax 运行原理

Ajax 相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验。
Ajax从零入门到精通_第5张图片

Ajax 的实现步骤

  1. 创建 Ajax 对象
var xhr = new XMLHttpRequest();
  1. 告诉 Ajax 请求地址以及请求方式
xhr.open('get', 'http://www.example.com');
  1. 发送请求
xhr.send();
  1. 获取服务器端给与客户端的响应数据
xhr.onload = function () {
     console.log(xhr.responseText);
 }

服务器端响应的数据格式

在真实的项目中,服务器端大多数情况下会以 JSON 对象作为响应数据的格式。当客户端拿到响应数据时,要将 JSON 数据和 HTML 字符串进行拼接,然后将拼接的结果展示在页面中。
在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输。

JSON.parse() // 将 json 字符串转换为json对象

请求参数传递

传统网站表单提交

<form method="get" action="http://www.example.com">
     <input type="text" name="username"/>
     <input type="password" name="password">
 form>
 
  • 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 请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,这些数据和信息要遵守规定好的格式。
Ajax从零入门到精通_第6张图片

请求参数的格式

  1. application/x-www-form-urlencoded
name=zhangsan&age=20&sex=
  1. application/json
{name: 'zhangsan', age: '20', sex: '男'}

在请求头中指定 Content-Type 属性的值是 application/json,告诉服务器端当前请求参数的格式是 json。

JSON.stringify() // 将json对象转换为json字符串

注意:get 请求是不能提交 json 对象数据格式的,传统网站的表单提交也是不支持 json 对象数据格式的。

获取服务器端的响应

Ajax 状态码

在创建ajax对象,配置ajax对象,发送请求,以及接收完服务器端响应数据,这个过程中的每一个步骤都会对应一个数值,这个数值就是ajax状态码。

0:请求未初始化(还没有调用open())
1:请求已经建立,但是还没有发送(还没有调用send())
2:请求已经发送
3:请求正在处理中,通常响应中已经有部分数据可以用了
4:响应已经完成,可以获取并使用服务器的响应了

xhr.readyState // 获取Ajax状态码

onreadystatechange 事件

当 Ajax 状态码发生变化时将自动触发该事件。
在事件处理函数中可以获取 Ajax 状态码并对其进行判断,当状态码为 4 时就可以通过 xhr.responseText 获取服务器端的响应数据了。

 // 当Ajax状态码发生变化时
 xhr.onreadystatechange = function () {
     // 判断当Ajax状态码为4时
     if (xhr.readyState == 4) {
         // 获取服务器端的响应数据
         console.log(xhr.responseText);
     }
 }

两种获取服务器端响应方式的区别

Ajax从零入门到精通_第7张图片

Ajax 错误处理

  1. 网络畅通,服务器端能接收到请求,服务器端返回的结果不是预期结果。

可以判断服务器端返回的状态码,分别进行处理。xhr.status 获取http状态码

  1. 网络畅通,服务器端没有接收到请求,返回404状态码。

检查请求地址是否错误。

  1. 网络畅通,服务器端能接收到请求,服务器端返回500状态码。

服务器端错误,找后端程序员进行沟通。

  1. 网络中断,请求无法发送到服务器端。

会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理。

低版本 IE 浏览器的缓存问题

问题:在低版本的 IE 浏览器中,Ajax 请求有严重的缓存问题,即在请求地址不发生变化的情况下,只有第一次请求会真正发送到服务器端,后续的请求都会从浏览器的缓存中获取结果。即使服务器端的数据更新了,客户端依然拿到的是缓存中的旧数据。
解决方案:在请求地址的后面加请求参数,保证每一次请求中的请求参数的值不相同。

xhr.open('get', 'http://www.example.com?t=' + Math.random());

3、Ajax 异步编程

同步异步概述

同步

  • 一个人同一时间只能做一件事情,只有一件事情做完,才能做另外一件事情。
  • 落实到代码中,就是上一行代码执行完成后,才能执行下一行代码,即代码逐行执行。
console.log('before'); 
console.log('after');

异步

  • 一个人一件事情做了一半,转而去做其他事情,当其他事情做完以后,再回过头来继续做之前未完成的事情。
  • 落实到代码上,就是异步代码虽然需要花费时间去执行,但程序不会等待异步代码执行完成后再继续执行后续代码,而是直接执行后续代码,当后续代码执行完成后再回头看异步代码是否返回结果,如果已有返回结果,再调用事先准备好的回调函数处理异步代码执行的结果。
console.log('before');
setTimeout(
    () => { console.log('last');
 }, 2000);
console.log('after');

Ajax 封装

问题:发送一次请求代码过多,发送多次请求代码冗余且重复。

解决方案:将请求代码封装到函数中,发请求时调用函数即可。

 ajax({ 
     type: 'get',
     url: 'http://www.example.com',
     success: function (data) { 
         console.log(data);
     }
 })

二、Ajax编程

1、模板引擎

模板引擎概述

作用:使用模板引擎提供的模板语法,可以将数据和 HTML 拼接起来。

官方地址: https://aui.github.io/art-template/zh-cn/index.html

使用步骤

  1. 下载 art-template 模板引擎库文件并在 HTML 页面中引入库文件
<script src="./js/template-web.js"></script>
  1. 准备 art-template 模板
 <script id="tpl" type="text/html">
     <div class="box"></div>
 </script>
  1. 告诉模板引擎将哪一个模板和哪个数据进行拼接
var html = template('tpl', {username: 'zhangsan', age: '20'});
  1. 将拼接好的html字符串添加到页面中
document.getElementById('container').innerHTML = html;
  1. 通过模板语法告诉模板引擎,数据和html字符串要如何拼接
<script id="tpl" type="text/html">
     <div class="box"> {{ username }} </div>
 </script>

2、案例

验证邮箱地址唯一性

Ajax从零入门到精通_第8张图片

  1. 获取文本框并为其添加离开焦点事件
  2. 离开焦点时,检测用户输入的邮箱地址是否符合规则
  3. 如果不符合规则,阻止程序向下执行并给出提示信息
  4. 向服务器端发送请求,检测邮箱地址是否被别人注册
  5. 根据服务器端返回值决定客户端显示何种提示信息

搜索框内容自动提示

Ajax从零入门到精通_第9张图片

  1. 获取搜索框并为其添加用户输入事件
  2. 获取用户输入的关键字
  3. 向服务器端发送请求并携带关键字作为请求参数
  4. 将响应数据显示在搜索框底部

省市区三级联动

Ajax从零入门到精通_第10张图片
1、通过接口获取省份信息
2、使用JavaScript获取到省市区下拉框元素
3、将服务器端返回的省份信息显示在下拉框中
4、为下拉框元素添加表单值改变事件(onchange)
5、当用户选择省份时,根据省份id获取城市信息
6、当用户选择城市时,根据城市id获取县城信息

3、FormData

FormData 对象的作用

1、模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式。
2、异步上传二进制文件

FormData 对象的使用

  1. 准备 HTML 表单
<form id="form">
     <input type="text" name="username" />
     <input type="password" name="password" />
     <input type="button"/>
form>
  1. 将 HTML 表单转化为 formData 对象
var form = document.getElementById('form'); 
var formData = new FormData(form);
  1. 提交表单对象
xhr.send(formData);

注意:
1、Formdata 对象不能用于 get 请求,因为对象需要被传递到 send 方法中,而 get请求方式的请求参数只能放在请求地址的后面。
2、服务器端 bodyParser 模块不能解析 formData 对象表单数据,我们需要使用formidable 模块进行解析。

FormData 对象的实例方法

  1. 获取表单对象中属性的值
formData.get('key');
  1. 设置表单对象中属性的值
formData.set('key', 'value');
  1. 删除表单对象中属性的值
formData.delete('key');
  1. 向表单对象中追加属性值
formData.append('key', 'value');

注意:set 方法与 append 方法的区别是,在属性名已存在的情况下,set 会覆盖已有键名的值,append会保留两个值。

FormData 二进制文件上传

<input type="file" id="file"/>
var file = document.getElementById('file')
// 当用户选择文件的时候
 file.onchange = function () {
     // 创建空表单对象
     var formData = new FormData();
     // 将用户选择的二进制文件追加到表单对象中
     formData.append('attrName', this.files[0]);
     // 配置ajax对象,请求方式必须为post
     xhr.open('post', 'www.example.com');
     xhr.send(formData);
 }

FormData 文件上传进度展示

// 当用户选择文件的时候
 file.onchange = function () {
     // 文件上传过程中持续触发onprogress事件
     xhr.upload.onprogress = function (ev) {
         // 当前上传文件大小/文件总大小 再将结果转换为百分数
         // 将结果赋值给进度条的宽度属性 
         bar.style.width = (ev.loaded / ev.total) * 100 + '%';
     }
 }

FormData 文件上传图片即时预览

在我们将图片上传到服务器端以后,服务器端通常都会将图片地址做为响应数据传递到客户端,客户端可以从响应数据中获取图片地址,然后将图片再显示在页面中。

xhr.onload = function () {
     var result = JSON.parse(xhr.responseText);
     var img = document.createElement('img');
     img.src = result.src;
     img.onload = function () {
         document.body.appendChild(this);
     }
 }

4、同源政策

Ajax请求限制

Ajax 只能向自己的服务器发送请求。比如现在有一个A网站、有一个B网站,A网站中的 HTML 文件只能向A网站服务器中发送 Ajax 请求,B网站中的 HTML 文件只能向 B 网站中发送 Ajax 请求,但是 A 网站是不能向 B 网站发送 Ajax请求的,同理,B 网站也不能向 A 网站发送 Ajax请求。

什么是同源

如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
http://www.example.com/dir/page.html

http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
https://www.example.com/dir/page.html:不同源(协议不同)

同源政策的目的

同源政策是为了保证用户信息的安全,防止恶意的网站窃取数据。最初的同源政策是指 A 网站在客户端设置的 Cookie,B网站是不能访问的。

随着互联网的发展,同源政策也越来越严格,在不同源的情况下,其中有一项规定就是无法向非同源地址发送Ajax 请求,如果请求,浏览器就会报错。

使用 JSONP 解决同源限制问题

jsonp 是 json with padding 的缩写,它不属于 Ajax 请求,但它可以模拟 Ajax 请求。

  1. 将不同源的服务器端请求地址写在 script 标签的 src 属性中
<script src="www.example.com"></script>
<script src=“https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  1. 服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。
const data = 'fn({name: "张三", age: "20"})';
 res.send(data);
  1. 在客户端全局作用域下定义函数 fn
function fn (data) { }
  1. 在 fn 函数内部对服务器端返回的数据进行处理
function fn (data) { console.log(data); }

JSONP 代码优化

  • 客户端需要将函数名称传递到服务器端。
  • 将 script 请求的发送变成动态请求。
  • 封装 jsonp 函数,方便请求发送。
  • 服务器端代码优化之 res.jsonp 方法。

CORS 跨域资源共享

CORS:全称为 Cross-origin resource sharing,即跨域资源共享,它允许浏览器向跨域服务器发送 Ajax 请求,克服了 Ajax 只能同源使用的限制。

Ajax从零入门到精通_第11张图片

origin: http://localhost:3000
Access-Control-Allow-Origin: 'http://localhost:3000'
Access-Control-Allow-Origin: '*'

Node 服务器端设置响应头示例代码:

app.use((req, res, next) => {
     res.header('Access-Control-Allow-Origin', '*');
     res.header('Access-Control-Allow-Methods', 'GET, POST');
     next();
 })

访问非同源数据 服务器端解决方案

同源政策是浏览器给予Ajax技术的限制,服务器端是不存在同源政策限制。

Ajax从零入门到精通_第12张图片

cookie复习

Ajax从零入门到精通_第13张图片

withCredentials属性

在使用Ajax技术发送跨域请求时,默认情况下不会在请求中携带cookie信息。

withCredentials:指定在涉及到跨域请求时,是否携带cookie信息,默认值为false

Access-Control-Allow-Credentials:true 允许客户端发送请求时携带cookie

三、jQuery 中的 Ajax

1、$.ajax()

$.ajax()方法概述

作用:发送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) {}
});
{
     data: 'name=zhangsan&age=20'
}

{
     contentType: 'application/json'
}

JSON.stringify({name: 'zhangsan', age: '20'})

作用:发送jsonp请求。

$.ajax({
    url: 'http://www.example.com',
    // 指定当前发送jsonp请求
    dataType: 'jsonp',
    // 修改callback参数名称
    jsonp: 'cb',
    // 指定函数名称
    jsonCallback: 'fnName',
    success: function (response) {} 
})

serialize方法

作用:将表单中的数据自动拼接成字符串类型的参数

var params = $('#form').serialize();
// name=zhangsan&age=30

2、$ .get、$ .post

$ .get()、$ .post()方法概述

作用:$ .get方法用于发送get请求,$ .post方法用于发送post请求。

$.get('http://www.example.com', {name: 'zhangsan', age: 30}, function (response) {}) $.post('http://www.example.com', {name: 'lisi', age: 22}, function (response) {})

3、Todo案例

为todo数据库添加账号

  1. 使用mongo命令进入mongodb数据库
  2. 使用use admin命令进入到admin数据中
  3. 使用db.auth(‘root’,‘root’)命令登录数据库
  4. 使用use todo命令切换到todo数据库
  5. 使用db.createUser({user: ‘itcast’, pwd: ‘itcast’, roles: [‘readWrite’]})创建todo数据库账号
  6. 使用exit命令退出mongodo数据库

展示任务列表

  1. 准备一个放置任务列表的数组
  2. 向服务器端发送请求,获取已存在的任务
  3. 将已存在的任务存储在任务列表数组中
  4. 通过模板引擎将任务列表数组中的任务显示在页面中

添加任务

  1. 为文本框绑定键盘抬起事件,在事件处理函数中判断当前用户敲击的是否是回车键
  2. 当用户敲击回车键的时候,判断用户在文本框中是否输入了任务名称
  3. 向服务器端发送请求,将用户输入的任务名称添加到数据库中,同时将任务添加到任务数组中
  4. 通过模板引擎将任务列表数组中的任务显示在页面中

删除任务

  1. 为删除按钮添加点击事件
  2. 在事件处理函数中获取到要删任务的id
  3. 向服务器端发送请求,根据ID删除任务,同时将任务数组中的相同任务删除
  4. 通过模板引擎将任务列表数组中的任务重新显示在页面中

更改任务状态

  1. 为任务复选框添加onchange事件
  2. 在事件处理函数中获取复选框是否选中
  3. 向服务器端发送请求,将当前复选框的是否选中状态提交到服务器端
  4. 将任务状态同时也更新到任务列表数组中
  5. 通过模板引擎将任务列表数组中的任务重新显示在页面中并且根据任务是否完成为li元素添加completed类名

修改任务名称

  1. 为任务名称外层的label标签添加双击事件,同时为当前任务外层的li标签添加editing类名,开启编辑状态
  2. 将任务名称显示在文本框中并让文本框获取焦点
  3. 当文本框离开焦点时,将用户在文本框中输入值提交到服务器端,并且将最新的任务名称更新到任务列表数组中
  4. 使用模板引擎重新渲染页面中的任务列表。

计算未完成任务数量

  1. 准备一个用于存储未完成任务数量的变量
  2. 将未完成任务从任务数组中过滤出来
  3. 将过滤结果数组的长度赋值给任务数量变量
  4. 将结果更新到页面中

显示未完成任务

  1. 为active按钮添加点击事件
  2. 从任务列表数组中将未完成任务过滤出来
  3. 使用模板引擎将过滤结果显示在页面中

清除已完成任务

  1. 为clear completed按钮添加点击事件
  2. 向服务器端发送请求将数据库中的已完成任务删除掉
  3. 将任务列表中的已完成任务删除调用
  4. 使用模板引擎将任务列表中的最后结果显示在页面中

4、全局事件

只要页面中有Ajax请求被发送,对应的全局事件就会被触发

.ajaxStart()     // 当请求开始发送时触发
.ajaxComplete()  // 当请求完成时触发

5、nprogress进度条插件

官宣:纳米级进度条,使用逼真的涓流动画来告诉用户正在发生的事情!

<link rel='stylesheet' href='nprogress.css'/>
<script src='nprogress.js'></script>
NProgress.start();  // 进度条开始运动 
NProgress.done();   // 进度条结束运动

四、RESTful 和 XML

1、RESTful 风格的 API

传统请求地址回顾

GET http://www.example.com/getUsers         // 获取用户列表
GET http://www.example.com/getUser?id=1     // 比如获取某一个用户的信息
POST http://www.example.com/modifyUser      // 修改用户信息
GET http://www.example.com/deleteUser?id=1  // 删除用户信息

RESTful API 概述

一套关于设计请求的规范。

GET: 获取数据
POST: 添加数据
PUT: 更新数据
DELETE: 删除数据

users => /users
articles => /articles

RESTful API 的实现

GET:http://www.example.com/users 获取用户列表数据

POST:http://www.example.com/users 创建(添加)用户数据

GET:http://www.example.com/users/1 获取用户ID为1的用户信息
PUT:http://www.example.com/users/1 修改用户ID为1的用户信息
DELETE:http://www.example.com/users/1 删除用户ID为1的用户信息

2、XML 基础

XML是什么

XML 的全称是 extensible markup language,代表可扩展标记语言,它的作用是传输和存储数据。

<students> 
     <student>
         <sid>001</sid>
         <name>张三</name>
         </student>
     <student>
         <sid>002</sid>
         <name>王二丫</name>
         </student>
 </students>

XML DOM

XML DOM 即 XML 文档对象模型,是 w3c 组织定义的一套操作 XML 文档对象的API。浏览器会将 XML 文档解析成文档对象模型。

你可能感兴趣的:(前端开发基础)