您现在的位置是:首页 >学无止境 >前端学习--Ajax(3) XHR/axios网站首页学无止境
前端学习--Ajax(3) XHR/axios
简介前端学习--Ajax(3) XHR/axios
一、XMLHttpRequest
1.1 概念
XMLHttpRequest(XHR)是一种用于在客户端和服务器之间发送HTTP请求的JavaScript API。它允许客户端在不重新加载整个页面的情况下向服务器发送请求,并根据服务器的响应更新页面的局部内容。Ajax是基于XHR封装的。
1.2 使用xhr发起get请求
步骤
- 创建XHR对象
- 调用XHR.open()函数
- 调用XHR.send()函数
- 监听xhr.onreadystatechange事件
let 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){ //固定写法 和数据对象中的status要区分
console.log(xhr.responseText)
}
}
1.3 XHR的readyState属性
0 | UNSENT | XHR对象已经创建,但是未调用open方法 |
1 | OPENED | open()方法已经被调用 |
2 | HEADERS_RECEIVED | send()方法已经被调用,响应头也被接受 |
3 | LOADING | 数据接收中,此时response属性已经包含部分数据 |
4 | DONE | Ajax请求完成,数据传输完成或失败 |
1.4 使用XHR发起带参数的get请求
let xhr = new XMLHttpRequest()
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)
}
}
1.5 查询字符串
get请求携带参数的本质是将参数以查询字符串的形式追加到url的后面
$.get('url',{name:'zs',age:20},function(){})
//等价于
$.get('url?name=zs&age=20',function(){})
1.6 URL编码
如果url中包含中文,要编码成英文
encodeURI()//编码
decodeURI()//解码
一般来说浏览器会自动解析url
1.7 使用xhr发起post请求
步骤
- 创建xhr对象
- 调用xhr.open()函数
- 设置Content-Type属性
- 调用xhr.send()函数,指定要发送的数据
- 监听xhr.onreadystatechange事件
let xhr = new XMLHttpRequest()
xhr.open('POST','http://www.liulongbin.top:3006/api/addbook')
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send('bookname=八月博客&author=august&publisher=洋槐出版社')
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText)
}
}
二、数据交换格式
服务器端与客户端之间的数据传输与交换的格式
前端的两种数据格式是XML与JSON
2.1 XML
Extensible Markup Language 可扩展标记语言,被设计用来传输和存储数据
传输效率低,用JS解析比较麻烦
2.2 JSON
JavaScript Object Notation,Javascript对象表示法,本质是字符串
轻量级的文本数据交换格式,作用上类似于XML
JSON包含对象和数组两种结构
对象结构
{
key:value,
key:value,
...
}
其中key必须是双引号包裹的英文字符串,value的数据类型可以是数字、字符串、布尔值、null、对象、数组六种类型,不允许出现function和undefined
数组结构
[ ]括起来的内容
数组结构的类型可以是数字、字符串、布尔值、null、对象、数组六种类型
JSON不能写注释,不能用单引号表示字符串,最外层必须是对象或数组格式
作用:在本地与网络传输数据
2.3 JSON与JS中对象的关系
JSON实际上是一种JavaScript对象的表示方式,本质是字符串
JSON.parse()
JSON转换为JS对象
JSON.stringfy()
JS对象转换为JSON
// JavaScript对象
const person = {
name: 'Alice',
age: 30,
hobbies: ['reading', 'traveling'],
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA'
}
};
// 将JavaScript对象转换为JSON格式字符串
const jsonStr = JSON.stringify(person);
console.log(jsonStr);
// 输出: {"name":"Alice","age":30,"hobbies":["reading","traveling"],"address":{"street":"123 Main St","city":"Anytown","state":"CA"}}
// 将JSON格式字符串转换回JavaScript对象
const jsonObj = JSON.parse(jsonStr);
console.log(jsonObj);
// 输出: { name: 'Alice', age: 30, hobbies: [ 'reading', 'traveling' ], address: { street: '123 Main St', city: 'Anytown', state: 'CA' } }
三、XMLHttpRequest Level2
3.1 认识
新功能
- 设置HTTP请求的时限
- 使用FormData对象管理表单数据
- 可以上传文件
- 获取数据传输的进度信息
3.2 设置HTTP请求时限
let xhr = new XMLHttpRequest()
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)
}
}
3.3 FormData对象管理表单数据
let fd = new FormData()
//追加数据
fd.append('uname','zs')
fd.append('age',18)
let xhr = new XMLHttpRequest()
xhr.open('POST','http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText)
console.log(JSON.parse(xhr.responseText))
}
}
3.4 使用formdata快速获取表单数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="" class="form1">
<input type="text" name="uname" autocomplete="off">
<input type="password" name="pw">
<button type="submit">提交</button>
</form>
<script>
let form = document.querySelector('.form1')
let xhr = new XMLHttpRequest()
form.addEventListener('submit',function(e){
e.preventDefault()
let fd = new FormData(form)
xhr.open('POST','http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText)
}
}
})
</script>
</body>
</html>
3.5 上传文件
原生JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="../lib/bootstrap.css">
<style>
img{
width: 300px;
}
.progress{
width: 300px;
margin: 10px;
}
</style>
</head>
<body>
<input type="file" name="" id="file1">
<button id="btnUpload">上传文件</button>
<div class="progress">
<div class="progress-bar progress-bar-striped active" style="width: 0%">
<span class="sr-only"></span>
</div>
</div>
<div>
<img src="" alt="">
</div>
<script>
const bt1 = document.querySelector('#btnUpload')
let xhr = new XMLHttpRequest()
let fd = new FormData()
bt1.addEventListener('click',function(){
let files = document.querySelector('#file1').files
if(files.length <= 0)return alert('请选择文件!')
//将用户上传的文件添加到formdata中
fd.append('avatar',files[0])
xhr.open('POST','http://www.liulongbin.top:3006/api/upload/avatar')//文件请求类型必须选择post
xhr.send(fd)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
let data = JSON.parse(xhr.responseText)
if(data.status === 200){
console.log(data)
document.querySelector('img').src = 'http://www.liulongbin.top:3006' + data.url
}else{
alert(data.message)
}
}
}
})
const span = document.querySelector('.sr-only')
const progress = document.querySelector('.progress-bar')
xhr.upload.onprogress = function(e){
if(e.lengthComputable){ //布尔值 表示当前上传的资源是否具有可计算的长度
let percentComplete = Math.ceil((e.loaded / e.total) * 100)
progress.style.width = `${percentComplete}%`
span.innerHTML = percentComplete + '%'
}
}
</script>
</body>
</html>
jQuery的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="file" name="" id="file1">
<button id="btnUpload">上传文件</button>
<div>
<img id="loading" src="./img/loading.gif" alt="" style="display:none;">
</div>
<script src="../lib/jquery.js" ></script>
<script>
$(function(){
//jq实现loading效果
$(document).ajaxStart(function(){
$('#loading').show()
})
$(document).ajaxStop(function(){
$('#loading').hide()
})
$('#btnUpload').on('click',function(){
let files = $('#file1')[0].files
if(files.length <= 0)return alert('请选择文件后再上传')
let fd = new FormData()
fd.append('avatar',files[0])
$.ajax({ //上传文件必须调用$.ajax
method:'POST',
url:'http://www.liulongbin.top:3006/api/upload/avatar',
data:fd,
processData:false, //不对formdata中的url进行编码 原样发送到服务器
contentType:false, //使用formdata默认的contentType
success:function(res){
console.log(res)
}
})
})
})
</script>
</body>
</html>
四、axios
比jQuery更加轻量,只专注于网络数据请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="getbt">GET</button>
<button id="postbt">POST</button>
<button id="axios">直接使用axios</button>
<script src="../lib/jquery.js" ></script>
<script src="../lib/axios.js"></script>
<script>
document.querySelector('#getbt').addEventListener('click',function(){
const url = 'http://www.liulongbin.top:3006/api/get'
const obj = {
name:'zs',
age:18
}
axios.get(url, {params:obj}).then(function(res){
console.log(res)
})
})
document.querySelector('#postbt').addEventListener('click',function(){
const url = 'http://www.liulongbin.top:3006/api/post'
const obj = {
name:'ls',
age:20
}
axios.post(url, obj).then(function(res){
console.log(res)
})
})
document.querySelector('#axios').addEventListener('click',function(){
const url = 'http://www.liulongbin.top:3006/api/get'
const obj = {
name:'ww',
age:22
}
axios({
method:'GET',
url:url,
params:obj,
//data:data, 如果是Post需要将参数放在data
}).then(function(res){
console.log(res)
})
})
</script>
</body>
</html>
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。