本课目标
- 理解什么是同步请求和异步请求
- 理解Ajax的请求原理
- 掌握Ajax的基本用法
- 掌握课堂案例
1. 同步请求与异步请求的区别
1.1 什么是同步请求
同步请求:发送请求后需要等待服务端响应,同步请求阻止代码的执行,这会导致屏幕上出现“冻结”和无响应的用户体验。
1.2 什么是异步请求
异步请求:当请求的响应数据完全收到之时,会执行一个指定的回调函数,而在执行异步请求的同时,浏览器会正常地执行其他事务的处理。
2. Ajax的基本介绍与XMLHttpRequest对象
AJAX 是异步的 JavaScript 和 XML(Asynchronous JavaScript And XML)。简单点说,就是使用 XMLHttpRequest 对象与服务器通信。它可以使用 JSON,XML,HTML 和 text 文本等格式发送和接收数据。AJAX 最吸引人的就是它的“异步”特性,也就是说它可以在不重新刷新页面的情况下与服务器通信,交换数据,或更新页面。
AJAX 最主要的两个特性做下列事:
在不重新加载页面的情况下发送请求给服务器。
接受并使用从服务器发来的数据。
XMLHttpRequest:XMLHttpRequest是Ajax的核心,
XMLHttpRequest
(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest
在 AJAX 编程中被大量使用。
2.1 Ajax提交Get请求
课堂案例:01.Ajax提交get请求.html
<!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> <script> /* 基于Ajax发送一个get请求 1.查看xmlHttpRequest的构造函数,如何创建xmlHttpReqyest 2.XMLHttpRequest.open()方法初始化一个新创建的请求,或重新初始化一个请求。 xhrReq.open(method, url, async, user, password); 3.XMLHttpRequest.send() 方法用于发送 HTTP 请求 在 XHR 请求中要发送的数据体。可以是: 比如说是POST请求,就需要把POST请求的参数传入,如果是GET请求,就不需要传入参数 4.处理服务端的响应内容 */ //1.创建XMLHttpRequest对象 const request = new XMLHttpRequest(); //2.方法初始化一个新创建的请求,GET请求的参数是在?后面 request.open("GET","http://www.你的有效的网站.cn/spboot/userLoginGetRequest?username=admin&password=66666") //3.发送请求 request.send(); //4.如何接受服务端的响应内容 /* 通过onreadystatechange来监听服务端响应的结果 只读属性 XMLHttpRequest.status 返回了响应中的数字状态码 XMLHttpRequest.responseText 在一个请求被发送后,从服务器端返回文本。 onreadystatechange 当 readyState 的值改变的时候,callback 函数会被调用 */ request.onreadystatechange = function(){ console.log(request.readyState) //响应完成并且响应成功的话,就获取服务端响应的内容 if(request.readyState==4&&request.status==200){ // console.log(request.status) console.log(request.responseText) } } </script> </body> </html>
2.2 Ajax提交Post请求
课堂案例:02.Ajax提交post请求.html
<!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> <script> /* 请求接口 http://www.有效的网站 为什么浏览器会报错? 是因为该接口只能够接受POST请求,通过浏览器访问是属于GET请求 There was an unexpected error (type=Method Not Allowed, status=405). 错误信息: 需要在请求的时候,加上头部信息 */ const request = new XMLHttpRequest(); //2.创建一个与服务器的链接 request.open("POST","http://www.有效的网站") //如果是post请求,要加上头部信息 request.setRequestHeader("Content-Type","application/x-www-form-urlencoded") //XMLHttpRequest.timeout 是一个无符号长整型数,代表着一个请求在被自动终止前所消耗的毫秒数 request.timeout = 1000; //如果时间内没法发出请求,就失败 //3.调用send方法,发送请求 request.send("username=admin&password=66666") //4.通过 onreadystatechange 绑定一个回调函数 request.onreadystatechange = function(){ if(request.readyState==4&&request.status==200){ console.log("post异步请求完成") console.log(request.responseText) } } </script> </body> </html>
2.3 中文编码的方式
课堂案例:03.中文字符编码方式.html
<!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> <script> /* 场景:当请求参数提交到服务端的时候,如果有特殊字符存在,需要进行编码, 服务端会自己解码 一个中文会被编码成3个字组成 encodeURIComponent 和 encodeURI的区别? encodeURIComponent支持的字符更多 */ const str = "比屋 教-育" //%E6%AF%94%E5%B1%8B%20%20%E6%95%99-%E8%82%B2 const result = encodeURI(str) console.log(str) console.log(result) //服务端解码: %E6%AF%94 const decodeStr = decodeURI("%E6%AF%94") console.log(decodeStr) console.log("------------") /* 对URL进行编码 http://www.biwuit.cn/spboot/userLoginGetRequest?username=admin&password=66666 */ const url = "http://www.biwuit.cn/spboot/userLoginGetRequest?username=张三&password=66666"; console.log(encodeURI(url)) console.log(encodeURIComponent(url)) </script> </body> </html>
2.4 JSON对象与字符串互相转换
JSON.parse()
方法用来解析 JSON 字符串,构造由字符串描述的 JavaScript 值或对象。提供可选的 reviver 函数用以在返回之前对所得到的对象执行变换 (操作)。JSON.stringify()
方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。课堂案例:04.JSON对象与字符串互相转换.html
-
<!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> <script> /* JSON:是一种数据格式,非常容易理解, 用途 客户端与服务端之间进行数据传递,客户端可以发送json格式的数据 到服务端,服务端也可以响应给客户端json格式的数据 首先是一个大括号,在大括号里面就是键值对组成的 { key:value key:value key:value key:value } { "username":"zhangsan" "age":"22" "gender":"男" "hobby":"篮球,足球" } 总结:jason的数据格式是javascript内置的,可以和jsvascript的对象互相转换, 注意的是json格式的数据的key是需要加双引号的 */ //1.创建一个json格式的字符串 const jsonStr = '{"username":"张三","age":"22"}' //2.创建以恶搞js对象 const obj = { username:"张三", age:20, gender:"男", hobby:"足球,篮球" } //3.可以把js对象转换成json格式的字符串吗? console.log(obj) console.log(obj.username) const ObjStr = JSON.stringify(obj) console.log(ObjStr) console.log(ObjStr.username) //只有对象才能通过 . 取值 console.log("-------------") //4.可以把json格式的字符串转换成js对象吗? console.log(jsonStr) const jsonObj = JSON.parse(jsonStr) console.log(jsonObj.username) console.log(jsonObj) </script> </body> </html>
总结:json的数据格式是javascript内置的,可以和javascirpt的对象互相转换。需要注意的是json格式的数据的key是需要加双引号的。
用途:主要是用于客户端与服务端之间的数据传递。
3. FormData对象的使用
FormData:
FormData
接口提供了一种表示表单数据的键值对key/value
的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为"multipart/form-data"
,它会使用和表单一样的格式。课堂案例:05.FormData对象的基本使用.html
-
<!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> <form action="http://www.有效的网站" id="form1"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="提交"> </form> <script> /* 问题:如果表单的输入项很多的话,需要手动的获取表单输入项的值,比较繁琐 有没有简单的方式? 可以使用FormDate() */ const request = new XMLHttpRequest(); const form1Obj = document.querySelector("#form1") const inputs = document.querySelectorAll("input") form1Obj.addEventListener("submit", function (e) { //参数表单对象作为参数,自动完成参数的收集 const formDataObj = new FormData(form1Obj) //阻止表单的提交 e.preventDefault(); //通过Ajax提交 request.open("POST", "http://www.有效的网站") //头部信息 如果数据格式是FormData,不需要头部信息 // request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //获取数据 // const usernameValue = inputs[0].value; // const passwordValue = inputs[1].value; // const args = "username="+usernameValue+"&"+"password="+passwordValue; //使用FormDate获取参数 console.log(formDataObj.get("username")) console.log(formDataObj.get("password")) request.send(formDataObj) // request.send(args) request.onreadystatechange = function () { if (request.readyState == 4 && request.status == 200) { console.log(request.responseText) } } }) </script> </body> </html>
FormData 的
get()
方法用于返回 FormData 对象中和指定的键关联的第一个值,如果你想要返回和指定键关联的全部值,那么可以使用 getAll() 方法。
4. json格式数据作为参数提交
课堂案例:06.json数据格式提交.html
<!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> <form action="http://www.有效的网站" id="form1"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="提交"> </form> <script> /* 需求:服务端接受的参数格式需要json的数据格式 我们掌握的参数格式:username=admin&password=123 提交参数个格式必须为:{"username":"admin","password":"123"} 需要把上面的数据格式转换为json格式 如何实现? */ const request = new XMLHttpRequest(); const form1Obj = document.querySelector("#form1") form1Obj.addEventListener("submit", function (e) { //阻止表单的提交 e.preventDefault(); //参数表单对象作为参数,自动完成参数的收集 const formDataObj = new FormData(form1Obj) //需要json的数据格式 const submitObj = {}; formDataObj.forEach(function(value,key){ //第一次遍历 username:admin //第二次遍历 passname:123 // console.log(value) // console.log(key) submitObj[key] = value; }) //把submitArgs对象转换为json格式字符串 const submitArgs = JSON.stringify(submitObj) console.log(submitArgs) request.open("POST", "http://www.有效的网站") request.send(submitArgs) request.onreadystatechange = function () { if (request.readyState == 4 && request.status == 200) { console.log(request.responseText) } } }) </script> </body> </html>
5. 文件上传的实现
课堂案例:07.文件上传案例实现.html
<!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> <!-- 需求:将图片上传到服务器 --> <input type="file" id="file1"><br> <button>上传图片</button><br> <!-- 显示上传的图片 src:填写服务器的地址 --> <img src="" alt="" height="700px" width="600px"> <script> /* 通过Ajax上传图片 */ const request = new XMLHttpRequest(); const fileObj = document.querySelector("#file1") const btnObj = document.querySelector("button") const imgObj = document.querySelector("img") //绑定事件 btnObj.addEventListener("click",function(){ //2.判断用户是否添加了文件 console.dir(fileObj) if(fileObj.files.length<=0){ return alert("请上传图片") } //3.将用户添加的文件绑定到formData对象 console.log("-----------") const formData = new FormData(); console.dir(formData) formData.append('files',fileObj.files[0]) //4.发送Ajax请求,需要通过post请求发送 request.open("POST","http://www.有效的网站") request.send(formData) request.onreadystatechange = function () { if (request.readyState == 4 && request.status == 200) { //获取服务端响应胡来的内容 //{"msg":"文件上传成功","fileName":"f78fc8ba-2553-4b1f-8b02-5fae2f39b3101.jpg","code":200} //服务端在存储文件的时候,因为考虑到文件名会相同覆盖,所以在服务端生成一个随机字符串来代替文件名 console.log(request.responseText) //5.把上传到服务端图片显示在当前页面 //6.需要判断服务端响应回来的消息是否是文件上传成功,如果是 才显示 const responseValue = JSON.parse(request.responseText) if(responseValue.msg=="文件上传成功"){ //会显到页面 imgObj.src = 'http://www.有效的网站/'+responseValue.fileName; } } } }) </script> </body> </html>