Ajax

Ajax (Asynchronous JavaScript And XML) ,即异步JavaScript和 XML,是一组用于在网页上进行异步数据交换的Web开发技术

Ajax可以在不刷新整个页面的情况下向服务器发起请求并获取数据,然后将数据插入到网页中的某个位置

这种技术能够实现增量式更新页面,提高用户交互体验,减少响应时间和带宽的消耗

使用Ajax技术时,可以通过JavaScript和XMLHttpRequest对象向服务器获取数据

在Ajax请求的过程中,可以通过定义回调函数的方式对请求的结果进行处理,回调函数会在请求完成后执行,通过这种方式可以更新页面内容或者响应用户操作

实现的功能

  • 异步更新页面内容(如搜索建议、聊天框等)
  • 在页面中特定区域显示动态数据
  • 提交表单数据而无需刷新整个页面
  • 与服务器进行交互,不会导致页面跳转或刷新

优点

  • 提高用户体验:通过减少页面的重载和刷新,使得网站变得更加灵活和动态
  • 减轻服务器负载:可以有效减少服务器接收到的请求次数和需要响应的数据量,从而减轻服务器的负担
  • 提高响应速度:可以异步获取数据并更新页面,从而提高响应速度
  • 增加交互性:使页面变得更加动态和可交互

潜在的问题

  • 对搜索引擎优化(SEO)劣势较大,对于需要SEO的项目,应慎重考虑

    SEO在爬虫抓取时无法抓取Ajax的URL和内容,如果需要做SEO,可以尝试服务端渲染(SSR技术)

  • 需要考虑数据安全性和网络安全性问题,并采取相应的措施加以防范

  • 不合适的使用,可能会降低网站质量和效率,所以需要根据实际需求来决定是否采用

使用Ajax

MDN Ajax文档

常规方法

请求进度

1
2
3
4
5
6
7
8
9
10
// 进度条
const progress = document.getElementById('progress')

const xhr = new XMLHttpRequest()

// 读取请求的进度,可以实现进度条
xhr.addEventListener('progress', (event)=> {
console.log(event.loaded, event.total)
progress.innerText = `${(event.loaded/event.total*100).toFixed(2)}%`
})

超时处理

1
2
3
4
5
6
7
8
9
const xhr = new XMLHttpRequest()

// 设置超时时间
xhr.timeout = 60000

// 超时监听
xhr.addEventListener('timeout', ()=> {
console.log('请求超时')
})

中断请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 停止请求按钮
const stop = document.getElementById('stop')

const xhr = new XMLHttpRequest()

// 中断请求
stop.addEventListener('click', ()=> {
// 中断了就不能再恢复了
xhr.abort()
})

// 中断监听
xhr.addEventListener('abort', ()=> {
console.log('请求中断')
})

发送Get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 发送请求按钮
const send = document.getElementById('send')

send.addEventListener('click', ()=> {
sendAjax()
})

const sendAjax = ()=> {
const xhr = new XMLHttpRequest()

// 参数1:请求方式 参数2:请求地址 参数3:是否异步(默认true
xhr.open('get', 'http://localhost:3000/api/txt', true)

// 监听后端返回的内容
// #region
// xhr.onreadystatechange = ()=> {
// // readyState值的含义
// // readyState=0:未初始化,XMLHttpRequest对象已创建,但未调用open方法
// // readyState=1:已打开,open方法已被调用,但send方法未被调用
// // readyState=2:已发送,send方法已被调用,请求已被服务器接收
// // readyState=3:正在接收,服务器正在处理请求并返回数据
// // readyState=4:已完成,服务器已经完成了数据传输
// // status的含义:200成功 400参数错误 401token错误 403没有权限 404未找到 500服务器错误
// if(xhr.readyState === 4 && xhr.status === 200) {
// // 后端返回的数据
// console.log(xhr.responseText)
// }
// }
// #endregion

// 或者直接用onload,在readyState=4时才触发,可以更直观地判断ajax请求是否成功
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
}

// 给后台发送的东西,一般用不到(因为前端一般是通过url传参的
xhr.send(null)
}

发送Post请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 发送请求按钮
const send = document.getElementById('send')

send.addEventListener('click', ()=> {
sendAjax()
})

const sendAjax = ()=> {
const xhr = new XMLHttpRequest()

xhr.open('post', 'http://localhost:3000/api/post', true)

// 设置请求头,要在open之后
// 传递json
xhr.setRequestHeader('Content-Type', 'application/json')
// 传递字符串
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

// 或者直接用onload,可以更直观地判断ajax请求是否成功
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
}

// 传送json数据时一定要序列化
xhr.send(JSON.stringify({name:"yajue",age:24}))
}

上传文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 文件上传元素
const file = document.getElementById('file')

file.addEventListener('change', ()=> {
const formData = new FormData()
// 把读取到的文件放到FormData实例中
// key(这里是'file')需要和后端接收名对应
// files是input file选中的文件
formData.append('file', file.files[0])
const xhr = new XMLHttpRequest()
xhr.open('post', 'http://localhost:3000/api/upload', true)
// 传输文件时,浏览器一般会自己设置这条请求头,所以不必自己设置
// 自己设置时,不知道boundary的分割格式,可能会出问题
// xhr.setRequestHeader('Content-Type', 'multipart/form-data')
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
}
xhr.send(formData)
})