目录
XMLHttpRequest的基本使用:
XMLHttpRequest(简称xhr)是浏览器提供的JavaScript对象,通过它可以请求服务器上的数据资源,jQuery重点Ajax函数,是基于xhr对象进行封装出来的。
利用xhr对象发起get数据请求:
主要分为四步骤:
- 创建xhr对象
- 调用open函数
- 调用send函数发起Ajax请求
-
监听 onreadystatechange 事件
代码如下:
<script>
// 使用xhr发起get请求
// 1. 创建 XHR 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open 函数
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
// 3 . 调用 send 函数发起Ajax请求
xhr.send()
// 4. 监听 onreadystatechange 事件
xhr.onreadystatechange = function () {
//监听xhr对象的请求状态readyState;与服务器响应的状态status
if (xhr.readyState === 4 && xhr.status === 200) {//固定写法判断
// 获取服务器响应的数据
console.log(xhr.responseText)
}
}
</script>
利用xhr发起post请求:
主要分为五步骤:
-
创建 xhr 对象
-
调用 open 函数
-
调用setRequestHeader函数 设置 Content-Type 属性 固定写法
-
调用 send 函数
-
监听事件onreadystatechange
数据交换格式:
数据交换格式两种:xml和JSON
xml被设计用来传输和储存数据,是数据的载体,xml格式臃肿,和数据无关的代码多,体积大,传输效率低
在JavaScript中解析xml比较麻烦 ,所以前端主学JSON
JSON即是JavaScript对象表示法本质是字符串使用文本表示一个js对象或数组信息
JSON是一种轻量级的文本数据交换格式 , JSON不能写注释 , 不能使用其他类型作为JSON的值 JSON在计算机与网络之间储存和传输数据
<script>
var jsonStr = '{"a": "Hello", "b": "world"}'//json字符串
var obj = JSON.parse(jsonStr)//转换为js对象叫做JSON反序列化
console.log(obj)
var obj2 = { a: 'hello', b: 'world', c: false }
var str = JSON.stringify(obj2)//转换为json叫做JSON序列化
console.log(str)//对象结构key:value中key,value使用英文双引号包裹的字符串 value数据类型可以是数字,字符串,布尔值,null,数组。对象6种类型
console.log(typeof str)
</script>
把数据对象转化为字符串的过程叫做序列化 ,把字符串转化为数据对象的过程叫做反序列化
使用JSON中的parse函数应用:
一般在xhr发起onreadstatechange事件中将数据转换为js对象称之为反序列化。
<script>
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
console.log(typeof xhr.responseText)
var result = JSON.parse(xhr.responseText)//转换为js对象
console.log(result)
}
}
</script>
定义自己的ajax库:
调用自己的itheiam函数模仿$.ajax()
<script>
itheima({
method:'post',
url:'http://www.liulongbin.top:3006/api/addbook',
data:{
bookname:'水浒传',
author:'施耐庵',
publisher:'北京图书出版社'
},
success: function(res){
console.log(res);
}
})
</script>
在js中定义ajax库:
function zhuanhuan(data) {
//定义一个将数据转换查询字符串的形式
var arr = [];
for (var i in data) {
//i为循环对象的属性
var ser = i + "=" + data[i];
arr.push(ser);
}
return arr.join("&"); //多个属性需要加入&符号
}
function itheima(options) {
var xhr = new XMLHttpRequest();
var qs = zhuanhuan(options.data); //需要的数据,需要转换为查询字符串形式
if (options.method.toUpperCase == "GET") {
//将options的方法转为大写请求
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);//将数据JSON转换为js对象
options.success(result);//将数据传入success函数中
}
}
}
xhr中设置请求时限:
<script>
var xhr = new XMLHttpRequest()
// 设置timeout属性可以设置HTTP请求的时限
xhr.timeout = 30//单位毫秒
// 设置超时以后的处理函数
xhr.ontimeout = function () {//对应的处理函数
console.log('请求超时了!');
}
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
</script>
Ajax中上传文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>
<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />
<script>
// 1. 获取到文件上传按钮
var btnUpload = document.querySelector('#btnUpload')
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click', function () {
// 3. 获取到用户选择的文件列表
var files = document.querySelector('#file1').files//files数组包含内容
if (files.length <= 0) {
return alert('请选择要上传的文件!')
}
console.log(files);
var fd = new FormData()
// 将用户选择的文件,添加到 FormData 中 avatar代表头像的意思
fd.append('avatar', files[0])
console.log(fd);
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
xhr.send(fd)
// 监听onreadystatechange事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText)//将数据转换为js对象
if (data.status === 200) {//判断上传是否成功
// 上传成功
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url//相对的文件地址需要加上根路径
} else {
// 上传失败
console.log('图片上传失败!' + data.message)
}
}
}
})
</script>
</body>
</html>
需要注意的是:将文件内容需要进行添加到 FormData 中再进行上传
计算文件的上传进度:
需要调用xhr中的onprogress事件注意事件要放在open函数之前才有效。、
在页面中可以渲染一个进度条布局使用bootstrap库进行渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./lib/bootstrap.css" />
<script src="./lib/jquery.js"></script>
</head>
<body>
<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>
<!-- bootstrap 中的进度条 -->
<div class="progress" style="width: 500px; margin: 15px 10px">
<div
class="progress-bar progress-bar-striped active"
style="width: 0%"
id="percent"
>
0%
</div>
</div>
<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />
<script>
// 1. 获取到文件上传按钮
var btnUpload = document.querySelector("#btnUpload");
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener("click", function () {
// 3. 获取到用户选择的文件列表
var files = document.querySelector("#file1").files;
if (files.length <= 0) {
return alert("请选择要上传的文件!");
}
var fd = new FormData();
// 将用户选择的文件,添加到 FormData 中
fd.append("avatar", files[0]);
var xhr = new XMLHttpRequest();
// // 监听文件上传的进度 xhr.upload.onprogress事件
// xhr.upload.onprogress = function (e) {
// if (e.lengthComputable) {//是一个布尔值,表示当前资源是否具有可计算的长度
// // 计算出上传的进度
// // e.loaded 代表已传输的字节 e.total 代表需传输的总字节
// var procentComplete = Math.ceil((e.loaded / e.total) * 100)//求进度
// console.log(procentComplete)
// // 动态设置进度条
// $('#percent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')
// }
// }
xhr.upload.onload = function () {
$("#percent")
.removeClass()
.addClass("progress-bar progress-bar-success");
};
// 监听文件上传的进度 xhr.upload.onprogress事件要放在open函数之前
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
//是一个布尔值,表示当前资源是否具有可计算的长度
// 计算出上传的进度
// e.loaded 代表已传输的字节 e.total 代表需传输的总字节
var procentComplete = Math.ceil((e.loaded / e.total) * 100); //求进度
console.log(procentComplete);
// 动态设置进度条
$("#percent")
.attr("style", "width: " + procentComplete + "%;")
.html(procentComplete + "%");
}
};
xhr.open("POST", "http://www.liulongbin.top:3006/api/upload/avatar");
xhr.send(fd);
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 {
// 上传失败
console.log("图片上传失败!" + data.message);
}
}
};
});
</script>
</body>
</html>