🌈个人主页:前端青山
🔥系列专栏:JavaScript篇
🔖人终将被年少不可得之物困其一生
依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript-AjAx
目录
AJAX
AJAX 的优势
AJAX 的使用
创建一个 ajax 对象
配置链接信息
发送请求
一个基本的 ajax 请求
ajax 状态码
readyStateChange
responseText
ajax的工作原理
使用 ajax 发送请求时携带参数
发送一个带有参数的 get 请求
发送一个带有参数的 post 请求
get与post的区别?
get
post
封装 AJAX
确定一下使用的方式
Promise
什么是Promise?
promise使用语法
Promise原型对象的方法
处理多个异步
Promise的静态方法
Promise中的三种状态
ASYNC/AWAIT
async 和 await 关键字
async 关键字的用法
await 关键字的用法
缺点
解决方案
AJAX
-
ajax
全名async javascript and XML
-
是前后台交互的能力
-
也就是我们客户端给服务端发送消息的工具,以及接受响应的工具
-
是一个 默认异步 执行机制的功能
-
XML与JSON:都是可以跨平台、跨语言的一种数据格式。
-
JSON的格式:
- [] : 写在[]中的字符串,必须使用双引号
- 原生: [‘a’,“b”]
- JSON: [“a”,“b”]
- {} : key 必须加双引号,value如果是字符串,必须加双引号
- 原生:{ name : ‘张三’} {name : “张三”} { ‘name’: ‘张三’} { “name”: “张三”}
- JSON: { “name” : “张三” }
- 在JSON的值中:不能出现 undefined/NaN/function/Infinity
- [] : 写在[]中的字符串,必须使用双引号
-
通过异步与服务器通信,将用户请求的数据通过回调函数返回,并利用javascript将数据动态的添加到页面中,且整个过程不需要重新加载整个页面就可以完成
AJAX 的优势
- 异步与服务器通信
- 不需要刷新页面就可以更新数据
- 减少服务器负担,实现前后端负载平衡
- 缺点: 搜索引擎的支持度不够,因为数据都不在页面上,搜索引擎搜索不到
- 缺点:没有历史记录
- 缺点:存在风险
AJAX 的使用
- 在 js 中有内置的构造函数来创建 ajax 对象
- 创建 ajax 对象以后,我们就使用 ajax 对象的方法去发送请求和接受响应
创建一个 ajax 对象
// 除IE6所有浏览器都支持的
const xhr = new XMLHttpRequest()
// IE6
const xhr = new ActiveXObject('Mricosoft.XMLHTTP')
- 上面就是有了一个 ajax 对象
- 我们就可以使用这个
xhr
对象来发送 ajax 请求了
配置链接信息
const xhr = new XMLHttpRequest()
// xhr 对象中的 open 方法是来配置请求信息的
// 第一个参数是本次请求的请求方式 get / post / put / ...
// 第二个参数是本次请求的 url
// 第三个参数是本次请求是否异步,默认 true 表示异步,false 表示同步
// xhr.open('请求方式', '请求地址', 是否异步)
xhr.open('get', './data.php')
- 上面的代码执行完毕以后,本次请求的基本配置信息就写完了
发送请求
const xhr = new XMLHttpRequest()
xhr.open('get', './data.php')
// 使用 xhr 对象中的 send 方法来发送请求
xhr.send()
- 上面代码是把配置好信息的 ajax 对象发送到服务端
一个基本的 ajax 请求
- 一个最基本的 ajax 请求就是上面三步
- 但是光有上面的三个步骤,我们确实能把请求发送的到服务端
- 如果服务端正常的话,响应也能回到客户端
- 但是我们拿不到响应
- 如果想拿到响应,我们有两个前提条件
- 本次 HTTP 请求是成功的,也就是我们之前说的 http 状态码为 200 ~ 299
- ajax 对象也有自己的状态码,用来表示本次 ajax 请求中各个阶段
ajax 状态码
- ajax 状态码 -
xhr.readyState
- 是用来表示一个 ajax 请求的全部过程中的某一个状态
readyState === 0
: 表示未初始化完成,也就是open
方法还没有执行readyState === 1
: 表示配置信息已经完成,也就是执行完open
之后readyState === 2
: 表示send
方法已经执行完成readyState === 3
: 表示正在解析响应内容readyState === 4
: 表示响应内容已经解析完毕,可以在客户端使用了
- 这个时候我们就会发现,当一个 ajax 请求的全部过程中,只有当
readyState === 4
的时候,我们才可以正常使用服务端给我们的数据 - 所以,配合 http 状态码为 200 ~ 299
- 一个 ajax 对象中有一个成员叫做
xhr.status
- 这个成员就是记录本次请求的 http 状态码的
- 一个 ajax 对象中有一个成员叫做
- 两个条件都满足的时候,才是本次请求正常完成
readyStateChange
-
在 ajax 对象中有一个事件,叫做
readyStateChange
事件 -
这个事件是专门用来监听 ajax 对象的
readyState
值改变的的行为 -
也就是说只要
readyState
的值发生变化了,那么就会触发该事件 -
所以我们就在这个事件中来监听 ajax 的
readyState
是不是到 4 了const xhr = new XMLHttpRequest() xhr.open('get', './data.php') xhr.send() xhr.onreadyStateChange = function () { // 每次 readyState 改变的时候都会触发该事件 // 我们就在这里判断 readyState 的值是不是到 4 // 并且 http 的状态码是不是 200 ~ 299 if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) { // 这里表示验证通过 // 我们就可以获取服务端给我们响应的内容了 } }
responseText
-
ajax 对象中的
responseText
成员 -
就是用来记录服务端给我们的响应体内容的
-
所以我们就用这个成员来获取响应体内容就可以
const xhr = new XMLHttpRequest() xhr.open('get', './data.php') xhr.send() xhr.onreadyStateChange = function () { if (xhr.readyState === 4 && /^2\d{2|$/.test(xhr.status)) { // 我们在这里直接打印 xhr.responseText 来查看服务端给我们返回的内容 console.log(xhr.responseText) } }
ajax的工作原理
前后端交互,首先需要创建一个XMLHttpRequest对象,通过这个对象的open方法与服务器建立连接,通过send方法将请求发送给服务器,最后通过事件监听,将后端请求的数据通过回调函数返回给前端。
使用 ajax 发送请求时携带参数
- 我们使用 ajax 发送请求也是可以携带参数的
- 参数就是和后台交互的时候给他的一些信息
- 但是携带参数 get 和 post 两个方式还是有区别的
发送一个带有参数的 get 请求
-
get 请求的参数就直接在 url 后面进行拼接就可以
const xhr = new XMLHttpRequest() // 直接在地址后面加一个 ?,然后以 key=value 的形式传递 // 两个数据之间以 & 分割 xhr.open('get', './data.php?a=100&b=200') xhr.send()
- 这样服务端就能接受到两个参数
- 一个是 a,值是 100
- 一个是 b,值是 200
发送一个带有参数的 post 请求
-
post 请求的参数是携带在请求体中的,所以不需要再 url 后面拼接
const xhr = new XMLHttpRequest() xhr.open('get', './data.php') // 如果是用 ajax 对象发送 post 请求,必须要先设置一下请求头中的 content-type // 告诉一下服务端我给你的是一个什么样子的数据格式 xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') // 请求体直接再 send 的时候写在 () 里面就行 // 不需要问号,直接就是 'key=value&key=value' 的形式 xhr.send('a=100&b=200')
application/x-www-form-urlencoded
表示的数据格式就是key=value&key=value
get与post的区别?
get
- 传递速度快
- 传递数据大小为1KB
- 参数在url地址后面传递
- get以明文方式传递参数,所以不安全。
- get会留下历史记录
post
-
传递速度慢
-
传递数据大小为 2MB
-
参数在http协议的请求体中传递
-
post传递参数相对安全。
-
不会留下历史记录
封装 AJAX
- ajax 使用起来太麻烦,因为每次都要写很多的代码
- 那么我们就封装一个 ajax 方法来让我们使用起来简单一些
确定一下使用的方式
-
因为有一些内容可以不传递,我们可以使用默认值,所以选择对象传递参数的方式
// 使用的时候直接调用,传递一个对象就可以 ajax({ url: '', // 请求的地址 type: '', // 请求方式 async: '', // 是否异步 data: '', // 携带的参数 dataType: '', // 要不要执行 json.parse success: function () {} // 成功以后执行的函数 })
- 确定好使用方式以后,就开始书写封装函数
Promise
什么是Promise?
ES6提出的异步编程解决方案.
承诺的意思,是一个专门用来解决异步 回调地狱 的问题
- 回调地狱,其实就是回调函数嵌套过多导致的
- 当代码成为这个结构以后,已经没有维护的可能了
- 所以我们要把代码写的更加的艺术一些
promise使用语法
// 检测机构
//resolve : 处理异步时成功的状态
//reject : 处理异步时失败的状态
new Promise((resolve,reject) => {
if(处理异步){
resolve([参数]);
}else{
reject([参数]);
}
})
Promise原型对象的方法
- then(([参数]) => {}) : 当Promise对象返回resolve时,可以通过then方法执行后续的操作.
- catch([参数] => {}) : 当promise对象返回reject时,可以通过catch方法执行后续的操作.
处理多个异步
new Promise((resolve,reject) => {
if(处理异步){
resolve([参数]);
}else{
reject([参数]);
}
})
.then(() => {
return new Promise(() => {
})
})
.then(() => {
return new Promise(() => {
})
})
……
.then(() => {
})
Promise的静态方法
Promise.all() 将调用所有的promse对象,全部返回resolve时,该对象才返回resolve。如果有一个promise返回reject时,该对象返回reject
Promise中的三种状态
- resolved(fulfilled) : 成功状态
- pending : 进行中状态
- rejected : 失败状态
-
这个时候,我们的代码已经改观了很多了
-
基本已经可以维护了
-
但是对于一个程序员来说,这个样子是不够的
-
我们还需要更加的简化代码
-
所以我们就需要用到一个 es7 的语法了
-
叫做 async/await
ASYNC/AWAIT
-
async/await
是一个 es7 的语法 -
这个语法是 回调地狱的终极解决方案
-
语法:
async function fn() { const res = await promise对象 }
async 和 await 关键字
- 注意: 需要配合的必须是 Promise对象
- 注意:Promise 语法的调用方案
- 意义:可以把异步代码写的看起来像同步代码
async 关键字的用法
- 直接书写在函数的前面,表示该函数是一个异步函数
- 意义: 表示在该函数内可以使用 await 关键字
await 关键字的用法
- 必须书写在一个有async关键字的函数内
- await 后面等待的内容必须是一个promise对象
- 本该使用then接收的结果,可以直接定义变量接收
缺点
- await 只能捕获到promise成功的状态
- 如果失败,会报错,终止程序继续执行
解决方案
- 使用 try catch语法
- 语法: try { 执行代码 } catch(err) { 执行代码 }
- 首先执行 try 里面的代码, 如果不报错, catch 的代码不执行了
- 如果报错, 不会爆出错误, 不会终止程序执行, 而是执行 catch 的代码, 把错误信息给到 err 参数
- 改变封装Promise的思路
- 让当前的 Promise 对象百分百成功,让成功和失败都按照 resolve 的形式来执行,只不过传递出去的参数, 记录一个表示成功或者失败的信息