1.
明天的内容其实挺多的,咱们缓缓来说。首先第一个是xhr的根本应用,什么是xhr?
XMLHTTPRequest是浏览器提供的js对象,能够申请服务器上的数据资源,包含咱们后面始终用的jq外面的三个申请资源的办法都是基于xhr来封装的。
那么首先咱们看到xhr的get申请怎么来实现
首先要创立xhr实例通过new来实现
而后调用open函数,外面值为申请形式以及url
第三步调用send函数
第四步监听onreadyStateChange事件在这个事件外面要留神一下申请状态和服务器响应状态的固定写法,还有服务器响应回的数据
<!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> <script> // 1.创立xhr对象 var xhr = new XMLHttpRequest() // 2.调用open函数 决定申请形式和url xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks') // 3.调用send函数 xhr.send() // 4.监听事件 xhr.onreadystatechange = function() { // 4.1留神申请状态和服务器响应状态固定写法 if (xhr.readyState ==4 && xhr.status == 200) { // 4.2获取相应的数据 console.log(xhr.response); } } </script></body></html>
1
咱们看到在监听申请状态变动事件里有一个readystate的属性这个属性示意ajax以后申请所处的状态,其中0示意xhr对象以创立,但申请未调用open。1示意已调用open函数。2示意已调用send函数。3示意数据接管中。最初4示意所有申请实现
那么xhr带参的get申请怎么来实现的呢?只须要在open函数的url外面接一个查问字符串即可
xhr.open('get', 'http://www.ssfddaf.com/api?na...')
那么什么是查问字符串?
在url开端加上?参数=值多个参数间用&来连贯这就是查问字符串,无论是jQuery的三个申请形式还是xhr指定的参数其本质都是在url后带查问字符串
这里还要理解一个点url编码与解码
url中只容许出线英文不容许中文等其余语种,所以他就会把除英文外其余语种转换为%结尾带两个字符的款式来代替
编码encodeURI('中文;) 解码decodeURI(%的字符)三组%示意一个中文
2.
接下来咱们看到xhr怎么发动post申请
第一步创建对象
第二部open函数把申请形式改为post
第三步设置content-type 这是一个固定写法
xhr.setRequestHeader(‘content-type’, ‘application/x-www-form-urlencoded’)
第四步调用send函数 post的参数在这里增加以查问字符串的形式增加进来
第五步监听事件
<!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> <script> // 1.创立xhr对象 var xhr = new XMLHttpRequest() // 2.调用open函数 xhr.open('post', 'http://www.liulongbin.top:3006/api/addbook') // 3.设置cententtype xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') // 4.调用send函数 xhr.send('bookname=水府传&author=我') // 5.监听事件 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } } </script></body></html>
3.
数据交换格局
即服务器与客户端之间进行数据传输与替换的格局,XML和JSON这两种
XML咱们用的比拟少,它是可扩大标记语言,跟html很类似
JSON
什么事json,就是js对象和数组的字符串表示法,其中实质还是一个字符串它是轻量级文本数据交换格局
它的构造为有两种对象构造和数组构造
对象构造
‘{key:value}’咋一看跟对象很类似,然而首先里面会有引号,其次键值是字符类型必须加双引号
数组构造
【a,a】
要留神的是键值的双引号,json中不能写正文,不能应用undefined和函数作为值
json和对象互转
obj = JSON.parse(json)(反序列化)
json = JSON.stringify(obj)(序列化)
4.
封装本人的ajax函数
①先封装一个解决data对象为查问字符串的函数
②封装函数xhr
③判断不同的申请类型达到不同的形式
这个总之记住一点就是xhr调用申请的总体步骤就没得问题
// 1.先封装函数解决传进来的参数为查问字符串 function revolveData(data) { var arr = [] for (var k in data) { arr[arr.length] = k + '=' + data[k] } var str = arr.join('&') return str }// console.log(revolveData({name : '张三', age : 19}));// 2。封装主体函数function ajaxMine(obj) { var xhr = new XMLHttpRequest() var str = revolveData(obj.data) xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var res = JSON.parse(xhr.response) obj.success(res) } } // 3.判断不同的申请,做到不同的操作 if (obj.method.toUpperCase() == 'GET') { xhr.open(obj.method, obj.url + '?' +str) xhr.send() } else if (obj.method.toUpperCase() == 'POST') { xhr.open(obj.method, obj.url) xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') xhr.send(str) }}
验证
<!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> <script src="./封装本人的ajax函数.js"></script> <script> /* ajaxMine({ method : 'get', url : 'http://www.liulongbin.top:3006/api/getbooks', data : { id : 2 }, success : function(res) { console.log(res); } }) */ ajaxMine({ method : 'post', url : 'http://www.liulongbin.top:3006/api/addbook', data : { bookname : '收首饰', author : '东风似旧', publisher : '身法' }, success : function(res) { console.log(res); } }) </script></body></html>
5.
xhr level2新个性
在咱们旧版的xhr毛病就是不反对文件上传而且没有进度信息只有完没完成
在咱们新版xhr
反对文件上传,有进度信息,还能够设置http时限,还可应用formdata对象治理表单数据
接下来我会一一开始xhr这四个新个性
5.1
首先第一个设置Http时限,也就是在规定工夫如果还没有实现申请工作那么这个申请就失败了
xhr.timeout = 2000
与之对应的还有一个ontimeout的事件在超时后会做些什么
<!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> <script> var xhr = new XMLHttpRequest() xhr.timeout = 50 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></body></html>
5..2
formdata治理表单
因为咱们ajax次要是用来提交表单数据的嘛,所以H5就新增了一个FormData对象用来模仿表单操作
①新建formdata对象
②为formdata增加表单项
③创立xhr
④用xhr实现申请
<!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> <script> // 1.创立FormData对象 var fd = new FormData() // 2.往里面增加表单项 fd.append('uname', '王五') fd.append('age' , 29) // 3,创立xhr对象 var xhr = new XMLHttpRequest() // 4.应用xhr对象制订申请类型与地址 xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata') // 5.间接提交,formdata对象,这与提交网页表单的成果齐全一样 xhr.send(fd) // 6.验证 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responsete); } } </script></body></html>
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=""> <input type="text" name="uname"> <input type="password" name="pwd"> <input type="submit" value="提交"> </form> <script> var form = document.querySelector('form') form.onsubmit = e => { e.preventDefault() var xhr = new XMLHttpRequest() var fd = new FormData(form) xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata') xhr.send(fd) xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } } } </script></body></html>
5.3
上传文件
①定义UI构造
②验证是否抉择了文件
③像formdata追加文件
④用xhr发动上传申请
⑤监听事件
<!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> <!-- 1.定义ui构造 --> <!-- 1.1文件抉择框 --> <input type="file"> <!-- 1.2上传按钮 --> <input type="submit" value="上传文件"> <!-- 1.3img标签 用来显示上传胜利后的图片 --> <img src="" alt=""> <script> // 2.验证是否上传了文件 var uploadBtn = document.querySelector('input:nth-of-type(2)') uploadBtn.addEventListener('click', function() { // 2.1留神这里这个。files它是一个数组寄存的是文件 let files = document.querySelector('input:first-child').files if (files.length > 0) { // 3.像formdata中追加文件 var fd = new FormData() // avator为头像伪装这里是上传的头像 fd.append('avatar', files[0]) // 4.应用xhr发动上传文件申请 var xhr = new XMLHttpRequest() xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd) // 5.监听事件 xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { // console.log(xhr.responseText); let imgData = JSON.parse(xhr.responseText) if (imgData.status == 200) { document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url } else { console.log('上传文件失败'); } } } } else { return alert('请上传文件') } }) </script></body></html>
5.4
显示上传进度
通过xhr.upload.onprogress事件来监听这外面有三个属性值得注意一下
<!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> <!-- 1.定义ui构造 --> <!-- 1.1文件抉择框 --> <input type="file"> <!-- 1.2上传按钮 --> <input type="submit" value="上传文件"> <!-- 1.3img标签 用来显示上传胜利后的图片 --> <img src="" alt=""> <script> // 2.验证是否上传了文件 var uploadBtn = document.querySelector('input:nth-of-type(2)') uploadBtn.addEventListener('click', function() { // 2.1留神这里这个。files它是一个数组寄存的是文件 let files = document.querySelector('input:first-child').files if (files.length > 0) { // 3.像formdata中追加文件 var fd = new FormData() // avator为头像伪装这里是上传的头像 fd.append('avatar', files[0]) // 4.应用xhr发动上传文件申请 var xhr = new XMLHttpRequest() // -------------------------------- // 1.上传进度监听事件 xhr.upload.onprogress = e => { // 2.参数一 e.lengthComputable是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去 if (e.lengthComputable) { // 参数二e.loaded已传输的字节 // 参数三e.total需传输的总字节 var percenComplete = Math.ceil((e.loaded / e.total) * 100) console.log(percenComplete); } } xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd) // 5.监听事件 xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { // console.log(xhr.responseText); let imgData = JSON.parse(xhr.responseText) if (imgData.status == 200) { document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url } else { console.log('上传文件失败'); } } } } else { return alert('请上传文件') } }) </script></body></html>
晓得了上传进度咱们就能够通过bootstrap来一个进度条板的上传进度
<!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="../day01/lib/bootstrap.css"></head><body> <!-- 1.定义ui构造 --> <!-- 1.1文件抉择框 --> <input type="file"> <!-- 1.2上传按钮 --> <input type="submit" value="上传文件"> <!-- 1.3img标签 用来显示上传胜利后的图片 --> <img src="" alt=""> <!-- 进度条 --> <div class="progress" style="width: 500px;"> <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"> 0% </div> </div> <script> // 2.验证是否上传了文件 var uploadBtn = document.querySelector('input:nth-of-type(2)') uploadBtn.addEventListener('click', function() { // 2.1留神这里这个。files它是一个数组寄存的是文件 let files = document.querySelector('input:first-child').files if (files.length > 0) { // 3.像formdata中追加文件 var fd = new FormData() // avator为头像伪装这里是上传的头像 fd.append('avatar', files[0]) // 4.应用xhr发动上传文件申请 var xhr = new XMLHttpRequest() // -------------------------------- // 1.监听事件 var program = document.querySelector('.progress-bar') xhr.upload.onprogress = e => { // 2.参数一 e.lengthComputable是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去 if (e.lengthComputable) { // 参数二e.loaded已传输的字节 // 参数三e.total需传输的总字节 var percenComplete = Math.ceil((e.loaded / e.total) * 100) // console.log(percenComplete); program.style.width = percenComplete + '%' program.innerText = '%' + percenComplete } } xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd) // 5.监听事件 xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { // console.log(xhr.responseText); let imgData = JSON.parse(xhr.responseText) if (imgData.status == 200) { document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url } else { console.log('上传文件失败'); } } } } else { return alert('请上传文件') } }) </script></body></html>
最初欠缺上传胜利的进度条
<!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="../day01/lib/bootstrap.css"></head><body> <!-- 1.定义ui构造 --> <!-- 1.1文件抉择框 --> <input type="file"> <!-- 1.2上传按钮 --> <input type="submit" value="上传文件"> <!-- 1.3img标签 用来显示上传胜利后的图片 --> <img src="" alt=""> <!-- 进度条 --> <div class="progress" style="width: 500px;"> <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"> 0% </div> </div> <script> // 2.验证是否上传了文件 var uploadBtn = document.querySelector('input:nth-of-type(2)') uploadBtn.addEventListener('click', function() { // 2.1留神这里这个。files它是一个数组寄存的是文件 let files = document.querySelector('input:first-child').files if (files.length > 0) { // 3.像formdata中追加文件 var fd = new FormData() // avator为头像伪装这里是上传的头像 fd.append('avatar', files[0]) // 4.应用xhr发动上传文件申请 var xhr = new XMLHttpRequest() // -------------------------------- // 1.监听事件 var program = document.querySelector('.progress-bar') xhr.upload.onprogress = e => { // 2.参数一 e.lengthComputable是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去 if (e.lengthComputable) { // 参数二e.loaded已传输的字节 // 参数三e.total需传输的总字节 var percenComplete = Math.ceil((e.loaded / e.total) * 100) // console.log(percenComplete); program.style.width = percenComplete + '%' program.innerText = '%' + percenComplete } } // ----------------------------------- // 2.上传胜利进度条变动 xhr.upload.onload = () => { program.className = '' program.className = 'progress-bar progress-bar-success' } xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd) // 5.监听事件 xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { // console.log(xhr.responseText); let imgData = JSON.parse(xhr.responseText) if (imgData.status == 200) { document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url } else { console.log('上传文件失败'); } } } } else { return alert('请上传文件') } }) </script></body></html>
6.
jQuery高级用法
用jq来实现文件上传
①定义ui构造和后面一样
②验证是否抉择文件
③向formdata追加文件
④应用jq发动上传申请
⑤jq实现loading成果 两个办法一检测到任何ajax开始或失败就会调用
<!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> <!-- 1.定义UI构造 --> <form action=""> <input type="file" name="file" id=""> </form> <!-- 这里呈现了一点小问题 我在前面打印res始终打印不进去而且反正就想数据被清了一下思来想去才晓得是我把button放在表单里了所以一点击就会造成默认行为 --> <button type="submit">上传图片</button> <img style="display: none;" src="../../../../HTML/04-阶段四 前后端交互/第四阶段:前后端交互阶段材料新/ajax课程材料/day3(7-12大节)/code/images/loading.gif" alt=""> <script src="../day01/lib/jquery.js"></script> <script> // 5.这个办法是侦听到所有的ajax申请就会开始执行 $(document).ajaxStart(function() { $('img').show() }) $(document).ajaxStop(function() { $('img').hide() }) // 2.验证是否抉择了文件 $('button').on('click', function() { // 这里须要将jq对象转为原生dom对象来应用files这个属性 var files = $('input')[0].files // console.log(files); if (files.length <= 0) { return alert('请抉择文件') } else { // 3.向formdata追加文件 var fd = new FormData() fd.append('avatar', files[0]) // 4.利用jq来发动上传申请 $.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></body></html>
7.
axios
明天的最初一个内容,什么事axios,专一于网络数据申请的库,相比于原生xhr更简略易用,相比于jq更轻量化
<!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> <script src="./axios.js"></script></head><body> <button>发动get申请</button> <script> var btn = document.querySelector('button') /* btn.onclick = function() { var url = 'http://www.liulongbin.top:3006/api/get' var obj = {name : '张三', age : 29} axios.get(url, {params: obj}).then(function(res) { console.log(res); }) } */ btn.onclick = () => { axios({ method : 'get', url : 'http://www.liulongbin.top:3006/api/get', params : {name : '张三', age : 29} }).then(res => console.log(res)) } </script></body></html><!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> <script src="./axios.js"></script></head><body> <button>发动post申请</button> <script> /* document.querySelector('button').onclick =function() { var url = 'http://www.liulongbin.top:3006/api/post' var obj = {location : '重庆', address : '江北'} axios.post(url, {obj}).then(res => console.log(res)) } */ document.querySelector('button').onclick = () => { axios({ method : 'post', url : 'http://www.liulongbin.top:3006/api/post', data : {name : '张三', age : 29} }).then(res => console.log(res)) } </script></body></html>
<!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="../day01/lib/bootstrap.css"></head><body> <!-- 1.定义ui构造 --> <!-- 1.1文件抉择框 --> <input type="file"> <!-- 1.2上传按钮 --> <input type="submit" value="上传文件"> <!-- 1.3img标签 用来显示上传胜利后的图片 --> <img src="" alt=""> <!-- 进度条 --> <div class="progress" style="width: 500px;"> <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"> 0% </div> </div> <script> // 2.验证是否上传了文件 var uploadBtn = document.querySelector('input:nth-of-type(2)') uploadBtn.addEventListener('click', function() { // 2.1留神这里这个。files它是一个数组寄存的是文件 let files = document.querySelector('input:first-child').files if (files.length > 0) { // 3.像formdata中追加文件 var fd = new FormData() // avator为头像伪装这里是上传的头像 fd.append('avatar', files[0]) // 4.应用xhr发动上传文件申请 var xhr = new XMLHttpRequest() // -------------------------------- // 1.监听事件 var program = document.querySelector('.progress-bar') xhr.upload.onprogress = e => { // 2.参数一 e.lengthComputable是一个布尔值,示意以后上传的资源是否具备可计算的长度要有能力进去 if (e.lengthComputable) { // 参数二e.loaded已传输的字节 // 参数三e.total需传输的总字节 var percenComplete = Math.ceil((e.loaded / e.total) * 100) // console.log(percenComplete); program.style.width = percenComplete + '%' program.innerText = '%' + percenComplete } } // ----------------------------------- // 2.上传胜利进度条变动 xhr.upload.onload = () => { program.className = '' program.className = 'progress-bar progress-bar-success' } xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd) // 5.监听事件 xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { // console.log(xhr.responseText); let imgData = JSON.parse(xhr.responseText) if (imgData.status == 200) { document.querySelector('img').src = 'http://www.liulongbin.top:3006' + imgData.url } else { console.log('上传文件失败'); } } } } else { return alert('请上传文件') } }) </script></body></html>