Ajax-3-xhr

Ajax-3

xhr基本使用

XMLHttpRequest(简称xhr)是浏览器提供的Javascript对象,通过它,可以请求服务器上的数据资源。之前所学的 jQuery中的Ajax函数,就是基于xhr对象封装出来的。

使用xhr发起GET请求

①创建 xhr 对象

②调用 xhr.open() 函数

③调用 xhr.send() 函数

④监听 xhr.onreadystatechange事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<script>
// 1. 创建 XHR 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open 函数
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
// 3. 调用 send 函数
xhr.send()
// 4. 监听 onreadystatechange 事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {//xhr.status不是返回数据中的status
// 获取服务器响应的数据
console.log(xhr.responseText)
}
}
</script>
</body>

带参数GET请求

1
2
3
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
URL地址末尾放上参数
?键=值&键=值

查询字符串

查询字符串(URL参数)是指在URL的末尾加上用于向服务器发送信息的字符串(变量)。

(get携带参数的本质:无论使用$.ajax(),还是使用$.get(),又或者直接使用xhr对象发起GET请求,当需要携带参数的时候,本质上,都是直接将参数以查询字符串的形式,追加到URL地址的后面,发送到服务器的。)

URL编码

使用英文字符去表示非英文字符

1
2
3
4
5
浏览器提供了 URL 编码与解码的 API,分别是:
encodeURI() 编码的函数
decodeURI() 解码的函数
encodeURI('')//传字符串参数
decodeURI('')

使用xhr发起POST请求

①创建 xhr 对象

②调用 xhr.open() 函数

③设置 Content-Type 属性(固定写法)

④调用 xhr.send() 函数,同时指定要发送的数据

⑤监听 xhr.onreadystatechange 事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<script>
// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open 函数
xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook')
// 3. 设置 Content-Type 属性
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 4. 调用 send 函数 也是查询字符串
xhr.send('bookname=水浒传&author=施耐庵&publisher=上海图书出版社')
// 5. 监听事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
</script>
</body>

数据交换格式

1.XML

  • 可扩展标记语言,与HTML类似
  • 被设计用来传输和储存数据,数据载体
  • 缺点
    • 格式臃肿,体积大,效率低
    • 在JS中解析较麻烦

2.JSON

JSON的英文全称是JavaScriptObjectNotation,即“JavaScript对象表示法”。简单来讲,JSON 就是 Javascript对数组组的字符串表示法,它使用文本表示一个JS对象或数组的信息,因此,==JSON 的本质是字符串==。

  • 所有的字符串用双引号包裹
  • 属性名必须用双引号包裹
  • 不能写注释
  • 最外层必须是对象或数组格式
  • 不能使用undefined或函数作为JSON值

两种结构

对象:

对象结构在 JSON中表示为{} 括起来的内容。数据结构为{key: value, key: value, … } 的键值对结构。其中,key
必须是使用英文的双引号包裹的字符串,value的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型。

数组:

数组结构在 JSON中表示为[] 括起来的内容。数据结构为[“java”,”javascript”,30, true … ]。数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型。

与js对象

从JSON字符串到js对象 反序列化

1
2
3
var jsonStr = '{"a": "Hello", "b": "world"}'
var obj = JSON.parse(jsonStr)
console.log(obj)

从js对象到JSON字符串 序列化

1
2
3
4
var obj2 = { a: 'hello', b: 'world', c: false }
var str = JSON.stringify(obj2)
console.log(str)
console.log(typeof str)

封装自己的ajax函数

1.定义options参数选项

2.处理data参数

3.定义itheima函数

4.判断请求的类型

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
function resolveData(data) {
var arr = []
for (var k in data) {
var str = k + '=' + data[k]
arr.push(str)
}

return arr.join('&')
}

// var res = resolveData({ name: 'zs', age: 20 })
// console.log(res)

function itheima(options) {//options是定义的参数选项,接收一个配置对象作为参数
var xhr = new XMLHttpRequest()

// 把外界传递过来的参数对象,转换为 查询字符串
var qs = resolveData(options.data)

if (options.method.toUpperCase() === 'GET') {
// 发起GET请求
xhr.open(options.method, options.url + '?' + qs)
xhr.send()
} else if (options.method.toUpperCase() === 'POST') {
// 发起POST请求
xhr.open(options.method, options.url)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(qs)
}

xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var result = JSON.parse(xhr.responseText)
options.success(result)
}
}
}

xhr level2新特性

①可以设置 HTTP 请求的时限

②可以使用 FormData对象管理表单数据

③可以上传文件

④可以获得数据传输的进度信息

设置HTTP请求时限

新版本的 XMLHttpRequest对象,增加了timeout属性,可以设置HTTP请求的时限:

1
2
3
4
5
6
xhr.timeout = 3000
//上面的语句,将最长等待时间设为 3000 毫秒。过了这个时限,就自动停止HTTP请求。与之配套的还有一个 timeout 事件,用来指定回调函数:
xhr.ontimeout = function(event){
alert('请求超时!')
}

FormData对象管理表单数据

提交表单数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
// 1. 创建 FormData 实例
var fd = new FormData()
// 2. 调用 append 函数,向 fd 中追加数据
fd.append('uname', 'zs')
fd.append('upwd', '123456')

var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
//直接提交fd
xhr.send(fd)

xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText))
}
}
</script>

获取网页表单的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
// 1. 通过 DOM 操作,获取到 form 表单元素
var form = document.querySelector('#form1')

form.addEventListener('submit', function (e) {
// 阻止表单的默认提交行为
e.preventDefault()

// 2.创建 FormData,快速获取到 form 表单中的数据
var fd = new FormData(form)

var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
//3.将fd传入服务器
xhr.send(fd)

xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText))
}
}
})
</script>

上传文件

新版 XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件。

实现步骤:

①定义 UI结构

1
2
3
4
5
6
7
<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>
<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />

②验证是否选择了文件

1
2
3
4
5
6
7
8
9
10
<script>
var btnUpload = document.querySelector('#btnUpload')
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click', function () {
// 3. 获取到用户选择的文件列表
var files = document.querySelector('#file1').files // 对象,length和0都是属性名
if (files.length <= 0) {
return alert('请选择要上传的文件!')
}
......

③向 FormData中追加文件

1
2
3
var fd = new FormData()
// 将用户选择的文件,添加到 FormData 中
fd.append('avatar', files[0]) //avatar是自定义的值

④使用 xhr发起上传文件的请求

1
2
3
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
xhr.send(fd)

⑤监听 onreadystatechange事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText)
if (data.status === 200) {
// 上传成功
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
} else { //根目录+返回的url
// 上传失败
console.log('图片上传失败!' + data.message)
}
}
}
})
</script>

显示文件上传进度

新版本的 XMLHttpRequest对象中,可以通过监听 xhr.upload.onprogress 事件,来获取到文件的上传进度。语法格式如下:

1
2
3
4
5
6
7
8
9
10
11
// 创建 XHR 对象
var xhr = new XMLHttpRequest()
// 监听 xhr.upload 的 onprogress 事件
xhr.upload.onprogress = function(e) {
// e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
if (e.lengthComputable) {
// e.loaded 已传输的字节
// e.total 需传输的总字节
var percentComplete = Math.ceil((e.loaded / e.total) * 100)
}
}

jQuery实现文件上传

步骤与xhr上传相同,值得注意的是用$.ajax()上传时有两个新的参数且不可缺少

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
<script>
$(function () {
// 监听到Ajax请求被发起了
$(document).ajaxStart(function () {
$('#loading').show()
})

// 监听到 Ajax 完成的事件
$(document).ajaxStop(function () {
$('#loading').hide()
})
//loading效果

$('#btnUpload').on('click', function () {
var files = $('#file1')[0].files
if (files.length <= 0) {
return alert('请选择文件后再上传!')
}

var fd = new FormData()
fd.append('avatar', files[0])

// 发起 jQuery 的 Ajax 请求,上传文件
$.ajax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
processData: false, //不可省略
contentType: false, //不可省略
success: function (res) {
console.log(res)
}
})
})
})
</script>
  • 注:上传文件只能用$.ajax(),POST方式
  • $(document).ajaxStart()函数会监听当前文档内所有的Ajax请求。

axios

专注于网络数据请求的库

axios.js

发起GET请求

1
axios.get('url', { params: { /*参数*/ } }).then(callback)
1
2
3
4
5
6
7
document.querySelector('#btn1').addEventListener('click', function () {
var url = 'http://www.liulongbin.top:3006/api/get'
var paramsObj = { name: 'zs', age: 20 }
axios.get(url, { params: paramsObj }).then(function (res) {
console.log(res.data) //res.data才是服务器返回的数据,res是axios封装的对象
})
})

发起POST请求

1
axios.post('url', { /*参数*/ }).then(callback)  参数直接放一个对象
1
2
3
4
5
6
7
document.querySelector('#btn2').addEventListener('click', function () {
var url = 'http://www.liulongbin.top:3006/api/post'
var dataObj = { address: '北京', location: '顺义区' }
axios.post(url, dataObj).then(function (res) {
console.log(res.data)
})
})

直接用axios

1
2
3
4
5
6
7
axios({
method'请求类型',
url'请求的URL地址',
data: { /* POST数据 */ },
params: { /* GET参数 */ }
}) .then(callback)

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
document.querySelector('#btn3').addEventListener('click', function () {
var url = 'http://www.liulongbin.top:3006/api/get'
var paramsData = { name: '钢铁侠', age: 35 }
axios({
method: 'GET',
url: url,
params: paramsData
}).then(function (res) {
console.log(res.data)
})
})

document.querySelector('#btn4').addEventListener('click', function () {
axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: {
name: '娃哈哈',
age: 18,
gender: '女'
}
}).then(function (res) {
console.log(res.data)
})
})

Ajax-3-xhr
https://wjcbolg.cn/2023/05/04/Ajax-3/
作者
JasonWang
发布于
2023年5月4日
许可协议
BY-JW