目录
XMLHttpRequest的基本使用
使用xhr发起GET请求
xhr对象的readyState属性
使用xhr发起带参数的GET请求
查询字符串
URL编码与解码
使用xhr发起POST请求
数据交换格式
XML
JSON
封装自己的Ajax函数
要实现的效果
定义options参数选项
处理data参数
定义itheima函数
判断请求的类型
全部js代码
调用itheima函数
XMLHttpRequest Level2的新特性
设置HTTP请求时限
FormData对象管理表单数据
上传文件
显示文件上传进度
jQuery高级用法
jQuer实现文件上传
jQuery实现loading效果
完整代码
axios
axios发起GET请求
axios发起POST请求
直接使用axios发起请求
步骤:
// 1. 创建xhr 对象
var xhr = new XMLHttpRequest();
// 2. 调用 open 函数 指定 请求方式 与 URL地址
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);
}
}
值 |
状态 |
描述 |
0 |
UNSENT |
XMLHttpRequest 对象已被创建,但尚未调用 open方法。 |
1 |
OPENED |
open() 方法已经被调用。 |
2 |
HEADERS_RECEIVED |
send() 方法已经被调用,响应头也已经被接收。 |
3 |
LOADING |
数据接收中,此时 response 属性中已经包含部分数据。 |
4 |
DONE |
Ajax 请求完成,这意味着数据传输已经彻底完成或失败。 |
// ...省略不必要的代码
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1')
// ...省略不必要的代码
var xhr = new XMLHttpRequest();
// 获取id为1的数据
xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks?id=1');
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
// 不带参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks
// 带一个参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks?id=1
// 带两个参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记
GET请求携带参数的本质
GET请求携带参数的本质:以查询字符串的形式来提交参数
// 要先引用jquery.js
$.get('http://www.liulongbin.top:3006/api/getbooks', { id: 1, bookname: '西游记' }, function (res) {
console.log(res);
})
$.ajax({
method: 'get',
url: 'http://www.liulongbin.top:3006/api/getbooks',
data: {
id: 2,
author: '曹雪芹'
},
success: function (res) {
console.log(res);
}
})
如何对URL进行编码与解码
浏览器提供了 URL 编码与解码的 API,分别是:
var str = '刘德华';
var str2 = encodeURI(str);
console.log(str2); // %E5%88%98%E5%BE%B7%E5%8D%8E
var str3 = decodeURI('%E5%BE%B7%E5%8D%8E');
console.log(str3); // 德华
步骤:
// 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=England');
// 5. 监听事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
XML和HTML的区别
XML 和 HTML 虽然都是标记语言,但是,它们两者之间没有任何的关系。
XML的缺点
什么是JSON
JSON的两种结构
对象结构:
数组结构:
数组结构在 JSON 中表示为 [ ] 括起来的内容。
数据结构为 [ "java", "javascript", 30, true … ] 。 里面字符串为双引号!!!
数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型。
JSON语法注意事项
JSON和JS对象的关系
//这是一个对象
var obj = {a: 'Hello', b: 'World'}
//这是一个 JSON 字符串,本质是一个字符串
var json = '{"a": "Hello", "b": "World"}'
JSON和JS对象的互转
var jsonstr = '{"a":"hello","b":"world"}';
var obj = JSON.parse(jsonstr);
console.log(obj); // {a: "hello", b: "world"}
var obj2 = { a: 'hello', b: 'world', c: false };
var str = JSON.stringify(obj2);
console.log(str); // {"a":"hello","b":"world","c":false}
console.log(typeof str); // string
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); // JSON结构的字符串
// 把JSON字符串转换成JS对象
var result = JSON.parse(xhr.responseText);
console.log(result);
}
}
序列化和反序列化
function resolveData(data) {
var arr = [];
for (var k in data) {
var str = k + '=' + data[k]; // 让属性名k = 属性值data[k]
arr.push(str);
}
return arr.join('&'); // 每个字符串用&进行拼接
}
function itheima(options) { // options是服务器传过来的对象参数
var xhr = new XMLHttpRequest();
// 将外界传过来的参数对象 处理为 查询字符串的格式,方便传给服务器
var qs = resolveData(options.data); // qs 是等会要发到服务器的数据
// 监听事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// xhr.responseText // 是一个JSON格式的字符串,把他转换成JS对象
var result = JSON.parse(xhr.responseText);
options.success(result); // 调用success函数
}
}
}
// 判断请求的类型
if (options.method.toUpperCase() === 'GET') {
// 发起GET请求
xhr.open('GET', options.url + '?' + qs); // 如果有参数,后面拼接qs参数
xhr.send();
} else if (options.method.toUpperCase() === 'POST') {
// 发起POST请求
xhr.open('POST',options.url);
// 设置Content-Type 属性 固定写法
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 提交查询参数
xhr.send(qs);
}
function resolveData(data) {
var arr = [];
for (var k in data) {
var str = k + '=' + data[k]; // 让属性名k = 属性值data[k]
arr.push(str);
}
return arr.join('&'); // 每个字符串用&进行拼接
}
// var res = resolveData({
// name: '刘德华',
// age: 18,
// sex: '男'
// })
// console.log(res); // name=刘德华&age=18&sex=男
function itheima(options) { // options是服务器传过来的对象参数
var xhr = new XMLHttpRequest();
// 将外界传过来的参数对象 处理为 查询字符串的格式,方便传给服务器
var qs = resolveData(options.data); // qs 是等会要发到服务器的数据
// 判断请求的类型
if (options.method.toUpperCase() === 'GET') {
// 发起GET请求
xhr.open('GET', options.url + '?' + qs); // 如果有参数,后面拼接qs参数
xhr.send();
} else if (options.method.toUpperCase() === 'POST') {
// 发起POST请求
xhr.open('POST',options.url);
// 设置Content-Type 属性 固定写法
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 提交查询参数
xhr.send(qs);
}
// 监听事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// xhr.responseText // 是一个JSON格式的字符串,把他转换成JS对象
var result = JSON.parse(xhr.responseText);
options.success(result); // 调用success函数
}
}
}
itheima({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
data: {
id: 1
},
success: function (res) {
console.log(res);
}
});
itheima({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/addbook',
data: {
bookname: '哈利破特',
author: '罗琳',
publisher: '英国'
},
success: function (res) {
console.log(res);
}
})
旧版XMLHttpRequest的缺点
XMLHttpRequest Level2的新功能
有时,Ajax 操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。
新版本的 XMLHttpRequest 对象,增加了 timeout 属性,可以设置 HTTP 请求的时限
var xhr = new XMLHttpRequest();
xhr.timeout = 3000; // 将最长等待时间设为 3000 毫秒
将最长等待时间设为 3000 毫秒,过了这个时限,就自动停止HTTP请求
与之配套的还有一个 timeout 事件,用来指定超时以后的回调函数
xhr.ontimeout = function(event){
alert('请求超时!')
}
var xhr = new XMLHttpRequest();
// 设置超时时间
xhr.timeout = 3000;
// 设置超时以后的回调函数
xhr.ontimeout = function () {
alert('请求超时了');
}
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);
}
}
FormData对象也可以用来获取网页表单的值
新版 XMLHttpRequest 对象,不仅可以发送文本信息,还可以上传文件。
实现步骤:
定义UI结构
验证是否选择了文件
// 验证是否选择了文件
// 1. 获取文件上传按钮
var btnUpload = document.querySelector('#btnUpload');
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click', function () {
// 3. 获取到用户选择的文件列表
var files = document.querySelector('#file1').files;
if (files.length <= 0) {
return alert('请选择要上传的文件!');
}
console.log('用户选择了待上传的文件');
})
向FormData中追加文件
// 4. 向formData中追加文件
var fd = new FormData();
fd.append('avatar', files[0]); // avatar 头像的意思 files[0]选择文件列表里的第一个
使用 xhr 发起上传文件的请求
// 5.使用xhr发起上传文件的请求
var xhr = new XMLHttpRequest();
// 调用 open 函数,指定请求类型与URL地址。其中,请求类型必须为 POST
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar');
// 发起请求
xhr.send(fd);
监听onreadystatechange事件
// 6. 监听onreadystatechange事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
console.log(data); // {message: "上传文件成功!", status: 200, url: "/uploads/1654605141873_67e417dcef7744f2859830ca58128130.jpg"}
if (data.status === 200) {
// 图片上传成功
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url;
} else {
// 上传失败
console.log('图片上传失败' + data.message);
}
}
}
上传文件完整代码
// 计算文件的上传进度
// 监听文件的上传进度
xhr.upload.onprogress = function (e) {
// e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
if (e.lengthComputable) {
// e.loaded 已传输的字节 e.total 文件传输需要的总字节
var percentComplete = Math.ceil((e.loaded / e.total) * 100); // Math.ceil() 向上取整
console.log(percentComplete);
}
}
1. 导入需要的库
2. 基于Bootstrap渲染进度条
3. 监听上传进度的事件
// 监听文件的上传进度
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
// e.loaded 已传输的字节 e.total 文件传输需要的总字节
var percentComplete = Math.ceil((e.loaded / e.total) * 100); // Math.ceil() 向上取整
console.log(percentComplete);
// 动态设置进度条
var percent = document.querySelector('#percent');
// 进度条宽度的变化
percent.style.width = percentComplete + '%';
// 进度条里面的文字
percent.innerHTML = percentComplete + '%';
}
}
4.监听上传完成的事件
upload.onload 上传完成
// 进度条上传成功 ,变成绿色的进度条
xhr.upload.onload = function () {
// 去除原来的样式
percent.className = '';
// 添加新的绿色的样式
percent.className = 'progress-bar progress-bar-success';
}
1. 定义UI结构
2. 验证是否选择了文件
$('#btnUpload').on('click', function () {
// 1. 将 jQuery 对象转化为 DOM 对象,并获取选中的文件列表,因为jQuery没有files属性
// files 是一个文件的数组
var files = $('#file1')[0].files;
// 2. 判断是否选择了文件
if (files.length <= 0) {
return alert('请选择文件后再上传');
}
})
3. 使用jQuery发起上传文件的请求
// 向FormData中追加文件
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,
// 不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值
processData: false,
// 不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发送到服务器
contentType: false,
success: function (res) {
console.log(res);
}
})
ajaxStart(callback)
// 监听到Ajax请求被发起了
$(document).ajaxStart(function () {
// 让这个元素显示出来
$('#loading').show();
})
ajaxStop(callback)
// 监听到ajax完成的事件
$(document).ajaxStop(function () {
$('#loading').hide();
})
axios.get('url', { params: { /*参数*/ } }).then(callback)
axios.post('url', { /*参数*/ }).then(callback)
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 也提供了类似于 jQuery 中 $.ajax() 的函数
axios({
method: '请求类型',
url: '请求的URL地址',
data: { /* POST数据 */ },
params: { /* GET参数 */ }
}) .then(callback)
直接使用axios发起GET请求
document.querySelector('#btn3').addEventListener('click', function () {
var url = 'http://www.liulongbin.top:3006/api/get';
var paramsData = { name: '刘德华', age: 18 };
axios({
method: 'GET',
url: url,
params: paramsData // GET 参数要通过 params 属性提供
}).then(function (res) {
console.log(res.data);
})
})
直接使用axios发起POST请求
document.querySelector('#btn4').addEventListener('click', function () {
axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
// POST 数据要通过 data 属性提供
data: {
name: 'HAHAHA',
age: 3
}
}).then(function (res) {
console.log(res.data);
})
})