Ajax基础
传统网站中存在的问题
- 网速慢的情况下,页面加载时间长,用户只能等待
- 表单提交后,如果一项内容不合格,需要重新填写所有表单内容
- 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间
什么是Ajax
Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)使用内置的XMLHttpRequest 和 fetch 对象,实现和服务端进行数据交互,可以实现页面无刷新更新数据,提高用户体验
Ajax的应用场景
- 页面上拉加载更多数据
- 列表数据无刷新分页
- 表单项离开焦点数据验证
- 搜索框提示文字下拉列表
Ajax的运行环境
Ajax 技术需要运行在网站环境中才能生效
Ajax运行原理及实现
Ajax运行原理
Ajax 相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验
Ajax发送get请求
// 1. 创建对象
const xhr = new XMLHttpRequest()
// 2. 配置参数
xhr.open('get', url, true) // boolean值表示是否异步
// 3. 绑定事件
xhr.onload = function() {
let responseText = JSON.parse(xhr.responseText)
console.log(responseText)
}
// 4. 发送请求
xhr.send()
服务器端响应数据的格式
在真实的项目中,服务器端大多数情况下会以JSON对象作为响应数据的格式。当客户端拿到响应数据时,要将 JSON 数据和 HTML 字符串进行拼接,然后将拼接的结果展示在页面中。在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输。
JSON.parse(xhr.responseText)
请求参数传递
- get请求方式
- post请求方式
请求参数的格式
- application/x-www-form-urlencoded
- 参数变成 key1=value1&key2=value2 的形式
- multipart/form-data
- 一般上传文件时使用
```javascript // 案例let formData = new FormData()
formData.append('username', 'abcdefg')
formData.append('password', '123456')
let url = 'http://rap2api.taobao.org/app/mock/244238/register'
let xhr = new XMLHttpRequest()
xhr.open('POST', url, true)
xhr.onload = function(){
if(xhr.status === 200 || xhr.status === 304) {
console.log(JSON.parse(xhr.responseText))
} else {
console.log('接口异常')
}
}
xhr.send(formData )
- 一般上传文件时使用
const $ = s => document.querySelector(s) const $submit = $(‘[type=submit]’) const $form = $(‘form’) const $msg = $(‘#msg’)
let url = ‘http://rap2api.taobao.org/app/mock/244238/register‘
$form.onsubmit = function(e) { e.preventDefault() //这里校验
let formData = new FormData($form)
let xhr = new XMLHttpRequest()
xhr.open(‘POST’, url, true)
xhr.onload = function(){
if(xhr.status === 200 || xhr.status === 304) {
let data = JSON.parse(xhr.responseText)
$msg.innerText = data.msg || data.errMsg
} else {
$msg.innerText = ‘接口异常’
}
}
xhr.send(formData )
}
<a name="Eqwri"></a>
### 获取服务器端的响应
**Ajax状态码**<br />在创建ajax对象,配置ajax对象,发送请求,以及接收完服务器端响应数据,这个过程中的每一个步骤都会对应一个数值,这个数值就是ajax状态码<br />0:请求未初始化(还没有调用open()<br />1:请求已经建立,但是还没有发送(还没有调用send())<br />2:请求已经发送<br />3:请求正在处理中,通常响应中已经有部分数据可以用了<br />4:响应已经完成,可以获取并使用服务器的响应了<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605084668138-bc9616a6-168c-45a8-9770-7f97e37e5310.png#height=90&id=vtz6I&margin=%5Bobject%20Object%5D&name=image.png&originHeight=111&originWidth=423&originalType=binary&ratio=1&size=3872&status=done&style=none&width=344)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605085138534-732e8fbb-7df1-4279-bc4a-1723437b3daf.png#height=315&id=EvCzD&margin=%5Bobject%20Object%5D&name=image.png&originHeight=462&originWidth=1051&originalType=binary&ratio=1&size=41823&status=done&style=none&width=717)<br />**两种获取服务器端响应方式区别**<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605084997050-ce8054db-be03-4641-8af7-39dda28bf94c.png#height=212&id=ld9ZG&margin=%5Bobject%20Object%5D&name=image.png&originHeight=212&originWidth=918&originalType=binary&ratio=1&size=19821&status=done&style=none&width=918)
<a name="gxMIQ"></a>
### Ajax错误处理
![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605085407568-3f9f5873-d5f1-45a4-8095-d7b2a4058dff.png#height=378&id=Bj68H&margin=%5Bobject%20Object%5D&name=image.png&originHeight=378&originWidth=787&originalType=binary&ratio=1&size=39010&status=done&style=none&width=787)
<a name="a5VMF"></a>
### 案例
```javascript
// 发送get请求
let url = 'http://rap2api.taobao.org/app/mock/244238/weather?city=北京'
let xhr = new XMLHttpRequest()
// 方法一
xhr.open('get', url, true)
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
console.log(JSON.parse(xhr.responseText))
} else {
console.log('数据异常')
}
}
}
xhr.onerror = function() {
console.log('服务器异常')
}
xhr.send()
// 方法二
xhr.open('GET', url, true)
xhr.onload = function(){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
console.log(JSON.parse(xhr.responseText)) // 将JSON字符串解析成对象
} else {
console.log('数据异常')
}
}
xhr.onerror = function(){ // 可选
console.log('服务器异常')
}
xhr.send()
// 发送post请求
let url = 'http://rap2api.taobao.org/app/mock/244238/login'
let xhr = new XMLHttpRequest()
xhr.timeout = 3000 //可选,设置请求超时时间
xhr.open('post', url, true)
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
xhr.onload = function(){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
console.log(JSON.parse(xhr.responseText))
} else {
console.log('响应异常')
}
}
xhr.ontimeout = function() {
console.log('请求超时')
}
xhr.onerror = function(){
console.log('服务器异常')
}
xhr.send('username=liudehua&password=12345678')
Ajax封装
const request = (url, params, onsuccess, onerror) => {
url = url + '?' + Object.entries(params).map(arr => arr[0] + '=' + arr[1]).join('&')
let xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onload = function(){
if(xhr.status === 200 || xhr.status === 304) {
onsuccess(JSON.parse(xhr.responseText))
} else {
onerror()
}
}
xhr.onerror = onerror
xhr.send()
}
request('http://rap2api.taobao.org/app/mock/244238/weathe', {city: '杭州'},
data => {
console.log('请求成功')
console.log(data)
},
() => {
console.log('接口异常')
}
)