首页 » 网站建设 » phpajax列队技巧_前端系列教程从理论到实践快速上手AJAX

phpajax列队技巧_前端系列教程从理论到实践快速上手AJAX

访客 2024-12-02 0

扫一扫用手机浏览

文章目录 [+]

(2)利用.then回调函数吸收结果,并做后续处理

axios({ url:'目标资源地址'}).then(result=>{ // 对做事器返回的数据做后续处理})3.案例:获取API中的省份列表,并在段落中显示出来;

<!doctype html><html lang="zh-cmn-Hans"><head> <meta charset="utf-8"><link rel="icon" href="./img/favicon.ico"> <title>axios利用</title> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script></head><body> <p class="my-p"></p></body><script> axios({ url:'http://hmajax.itheima.net/api/province' }).then(result=>{ // 对做事器返回的数据做后续处理 console.log(result.data.list.join('<br>')); // 把准备好的省份列表插入到页面 document.querySelector('.my-p').innerHTML = result.data.list.join('<br>'); })</script></html>二、URL统一资源定位符1.URL的观点

url是什么?URL是统一资源定位符,用于访问做事器上的资源;构造由协议、域名、资源路径组成;

phpajax列队技巧_前端系列教程从理论到实践快速上手AJAX

2.URL查询参数

url参数查询语法:

phpajax列队技巧_前端系列教程从理论到实践快速上手AJAX
(图片来自网络侵删)

http://xxx.com/xxx/xxx?参数名1=值1&参数名2=值23.axios查询参数

利用axios供应的params选项:

axios({ url:'目标资源地址', params:{ 参数名:值 }}).then(result=>{ // 对做事器返回的数据做后续处理})

实际上axios在运行时会把params中的内容自动拼接到url?参数名=值上面;

4.案例:地区查询

在ES6中如果属性名和变量同名,可以只写一个;

通过省份和城市名查询该城市的所有区县;

document.querySelector('.sel-btn').addEventListener('click',() => { let pname = document.querySelector('.province').value; let cname = document.querySelector('.city').value; // 基于axios获取做事器数据 axios({ url: "http://hmajax.itheima.net/api/area", params: { pname, cname } }).then(result => { let list = result.data.list; // 利用map函数将list映射到新的列表中theLi中 let theLi = list.map(areaName => `<li class="list-group-item">${areaName}</li>`).join('') console.log(theLi); //将结果插入到元素中显示出来 document.querySelector('.list-group').innerHTML = theLi; })})5.常用的要求方法

axios配置要求方法怎么写?

GET方法是默认的可以省略,在参数列表中,如果是get方法则用params,如果是post方法则用data;

axios({ url:'目标资源地址', method:'要求方法', params:{ 参数名:值 }}).then(result=>{ // 对做事器返回的数据做后续处理})6.axios缺点处理

在axios要求缺点时,通过调用catch方法传入回调函数并定义形参;例如在用户注册失落败时,通过弹窗提示用户缺点缘故原由。

axios({ // 要求选项}).then(result=>{ // 对做事器返回的数据做后续处理}).catch(error=>{ // 处理缺点})三、http协议1.要求报文

Http协议:规定了浏览器发送以及做事器返回内容的格式;

要求报文:浏览器按照Http协议哀求的格式,发送给做事器的内容

要求报文的组成部分有:

要求行:要求方法、URL、协议要求头:以键值对的格式携带附加的信息空行:分隔要求头,空行之后是发送给做事器的资源、要求体:发送的资源

在浏览器中怎么查看要求报文:

在浏览器的浏览器开拓者工具的网络面板中,选择Fetch/XHR中查看,

要求行和要求头在标头选项中,要求体在载荷选项中;

在故障排查时可以查看要求报文的要求体内容是否精确;

2.相应报文

相应报文的组成部分有:

相应行(状态行):协议、HTTP相应状态码、状态信息相应头:以键值对的格式携带附加信息,比如:Content-Type空行:分隔相应头,空行之后是做事器返回的资源相应体:返回的资源

HTTP相应状态码:用来表明要求是否成功,紧张含义如下:

四.接口文档案例

根据后真个接口文档,前端利用ajax进行调用;

示例API文档:https://apifox.com/apidoc/project-1937884/doc-1695440

1.案例-用户登录点击登录时,判断用户名和密码长度;提交数据和做事器通信提示

// 点击登录时,用户名和密码长度判断,并提交数据和做事器通信// 定义一个函数用于显示提示框function showAlert(msg, isSuccess) {const alert = document.querySelector(".alert");let alertStyle = isSuccess ? "alert-success" : "alert-danger";alert.innerHTML = msg;alert.classList.add("show");alert.classList.add(alertStyle);// 设置一个定时器3s后隐蔽提示框setTimeout(() => {alert.classList.remove("show");alert.classList.remove(alertStyle);}, 3000);}// 登录点击事宜document.querySelector(".btn-login").addEventListener("click", function () {// 获取用户名和密码const username = document.querySelector(".username").value;const password = document.querySelector(".password").value;// 对长度做判断if (username.length < 8) {console.log("用户名长度不能低于8");showAlert("用户名长度不能低于8", false);return;}if (password.length < 6) {console.log("密码长度不能低于6");showAlert("密码长度不能低于6", false);return;}axios({method: "post",url: "http://hmajax.itheima.net/api/login",data: { username, password,},}).then((result) => { console.log(result.data.message); showAlert(result.data.message, true);}).catch((error) => { console.log(error.response.data.message); showAlert(error.response.data.message, false);});});

2.form-serialize插件

利用form-serialize插件快速网络表单元素的值,获取结果的键值对,根据表单元素中的name属性获取键;

语法:

const data = serialize(form, {hash: true, empty:true})/ 利用serialize函数,快速网络表单元素的值 参数1:要获取的表单名称; 参数2:配置工具 hash:设置获取数据构造 - false:获取到的是url查询字符串 - true:获取到的是JS工具 empty:设置是否获取空值 - false: 不获取空值 - true: 可以获取到空值/

利用方法:

引入插件,调用serialize方法获取到表单元素的值,表单元素的name属性会成为返回工具的属性名;

将上面用户登录的案例利用form-serialize插件获取表单的值,下面是实际的写法:

// 点击登录时,用户名和密码长度判断,并提交数据和做事器通信// 定义一个函数用于显示提示框function showAlert(msg, isSuccess) {const alert = document.querySelector(".alert");let alertStyle = isSuccess ? "alert-success" : "alert-danger";alert.innerHTML = msg;alert.classList.add("show");alert.classList.add(alertStyle);// 设置一个定时器3s后隐蔽提示框setTimeout(() => {alert.classList.remove("show");alert.classList.remove(alertStyle);}, 3000);}// 登录点击事宜document.querySelector(".btn-login").addEventListener("click", function () {// 利用form-serialize插件const form = document.querySelector(".form-example");const data = serialize(form, { hash: true, empty: true });// 利用解构赋值的办法获取工具中用户名和密码const { username, password } = data;// 对长度做判断if (username.length < 8) {console.log("用户名长度不能低于8");showAlert("用户名长度不能低于8", false);return;}if (password.length < 6) {console.log("密码长度不能低于6");showAlert("密码长度不能低于6", false);return;}axios({method: "post",url: "http://hmajax.itheima.net/api/login",data: { username, password,},}).then((result) => { console.log(result.data.message); showAlert(result.data.message, true);}).catch((error) => { console.log(error.response.data.message); showAlert(error.response.data.message, false);});});3.Bootstrap弹框

功能:不离开当前页面,显示单独内容,供用户操作;调用弹窗可以通过两种办法:属性掌握和JS掌握;

利用方法:

(1)引入bootstrap.css与bootstrap.js

(2)给启动弹框的组件添加bootstrap属性,显示弹框须要两个属性,分别是data-bs-toggle和data-bs-target

<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target=".my-box">显示弹框</button>

(3)通过自定义属性,掌握弹框的显示和隐蔽,隐蔽弹框须要设置属性data-bs-dismiss="modal"

通过属性掌握弹窗的显示和隐蔽详细写法如下:

<div class="container mt-3"> <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target=".my-box">显示弹框</button> <!-- 弹框标签 --> <div class="modal my-box" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">请输入姓名</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <span>姓名</span> <input type="text" class="form-contorl" placeholder="默认姓名"> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal"> 取消 </button> <button type="button" class="btn btn-primary"> 保存 </button> </div> </div> </div> </div></div>

通过JS掌握,显示或隐蔽弹框:

// 创建弹框工具const modalDom = document.querySelector('.my-box');const modal = new bootstrap.Modal(modalDom);// 显示弹框modal.show();// 隐蔽弹框modal.hide();4.案例:图书管理管理系统

获取图书列表的的API地址http://hmajax.itheima.net/api/books

a.获取内容并渲染到网页上

这里重点须要节制的技巧是利用map将列表工具中的元素映射到html元素中,并进行字符串拼接的过程。
map函数可以传入三个参数(element、index、array),详细用法可见:https://www.freecodecamp.org/chinese/news/javascript-map-how-to-use-the-js-map-function-array-method/

window.addEventListener('load',()=>{ const creator = '小雨'; // 封装一个函数,获取并渲染图书列表 function getBookList(){ axios({ url: 'http://hmajax.itheima.net/api/books', params: { creator, } }).then(result => { const bookList = result.data.data; console.log(bookList); const bookItemHtml = bookList.map((item,index) => { return `<tr> <td>${index + 1}</td> <td>${item.bookname}</td> <td>${item.author}</td> <td>${item.publisher}</td> <td> <span class="del">删除</span> <span class="edit">编辑</span> </td> </tr>` }).join(''); document.querySelector('.list').innerHTML = bookItemHtml; }) } // 实行函数 getBookList()})

b.添加图书信息

// 目标2:添加图书信息 // 获取弹窗信息const addModalDom = document.querySelector('.add-modal');const addModal = new bootstrap.Modal(addModalDom);document.querySelector('.add-btn').addEventListener('click',()=>{ // 获取表单信息 const bookItemForm = document.querySelector('.add-form'); const bookItem = serialize(bookItemForm,{hash:true,empty:true}); // 提交表单信息 axios({ url: 'http://hmajax.itheima.net/api/books', method: 'post', data:{ // 这里的...是工具展开运算符 ...bookItem, // 这里的creator是一个全局变量 creator } }).then(result => { // 添加成功后要求重新渲染页面 getBookList(); // 重置表单,防止点击添加按钮后,上一次添加的内容还在 bookItemForm.reset(); // 隐蔽弹框 addModal.hide(); })});c.删除图书信息

思路:

a.绑定点击事宜获取图书id

b.调用删除接口

c.刷新图书列表

由于每一行图书信息是动态天生的,如果给每一行图书的删除按钮添加点击事宜,则须要委托其父级元素设置点击事宜。
再定义一个判断条件如果点击的元素中含有del类,则获取其父元素的id。

在渲染图书列表时就给删除按钮的父级元素创建一个自定义属性data-id,在点击事宜中,查询父元素的id属性即可通过AJAX删除指定ID的元素列表;

在接口文档中看到须要供应PATH参数,这是一种新的传参办法(路径传参)

将URL改为模板字符串即可。

// 目标3:删除图书信息document.querySelector('.list').addEventListener('click',function(e) { if(e.target.classList.contains('del')){ // 获取图书id const id = e.target.parentNode.dataset.id; console.log(id); // 调用删除接口 axios({ method: 'delete', url: `http://hmajax.itheima.net/api/books/${id}`, }).then(result =>{ // 刷新图书列表 getBookList(); }); }})d.编辑图书信息

实现该功能紧张须要完成以下部分的内容:

编辑弹窗的显示和隐蔽;

获取当前图书的ID并通过查询接口获取图书信息添补到弹窗中;

点击提交按钮时,提交表单中的内容到后台,并重新渲染前端页面内容;

// 目标4:编辑图书信息// 获取编辑弹窗信息const editModalDom = document.querySelector('.edit-modal');const editModal = new bootstrap.Modal(editModalDom);document.querySelector('.list').addEventListener('click',function(e){ if(e.target.classList.contains('edit')){ // 点击编辑按钮打开弹框 editModal.show(); // 获取图书id const theId = e.target.parentNode.dataset.id; // 获取图书详情信息 axios({ url: `http://hmajax.itheima.net/api/books/${theId}`, }).then(result => { const bookObj = result.data.data; const keys = Object.keys(bookObj); console.log(keys); keys.forEach(key => { document.querySelector(`.edit-form .${key}`).value = bookObj[key]; }); }); }})// 点击修正按钮后保存数据提交到做事器document.querySelector('.edit-btn').addEventListener('click',function(){ // 获取编辑表单信息 const editForm = document.querySelector('.edit-form'); // 保存修正后的表单内容 const {id,bookname,author,publisher} = serialize(editForm,{hash:true,empty:true}); // 将表单中的内容提交到做事器 axios({ method: 'put', url: `http://hmajax.itheima.net/api/books/${id}`, data: { id, bookname, author, publisher, creator } }).then(() => { // 刷新页面 getBookList(); // 隐蔽弹窗 editModal.hide(); });})5.案例:图片上传

图片上传的思路:

(1)获取图片文件工具

给input标签添加一个change事宜;

(2)利用FormData携带图片文件

const fd = new FormData()fd.append(参数名,值)

(3)提交表单数据到做事器

通过ajax将图片提交到做事器,并拿到后端返回的图片URL;

document.querySelector('.upload').addEventListener('change',(e)=>{ // 获取图片文件 console.log(e.target.files[0]); // 利用FormData携带图片文件 const fd = new FormData(); fd.append('img',e.target.files[0]) // 提交到做事器 axios({ url: 'http://hmajax.itheima.net/api/uploadimg', method: 'POST', data: fd }).then(result => { console.log(result.data.data); const imgurl = result.data.data.url; document.querySelector('.my-img').src = imgurl; })})6.案例:改换网站背景

实现一个案例,点击按钮上传图片,并更换网页背景,页面刷新后依然不变;

思路:

设置一个file类型的input标签,选中本地图片后,添加一个change事宜,将图片以FormData的办法通过Ajax提交到后端做事器;获取后端返回的url,给body标签授予backgroundImage属性,从而实现背景图片的改换;上传成功后保存url到本地存储localStorage.setItem(key,value);

window.addEventListener('load',() => { // 逻辑 document.querySelector('.bg-ipt').addEventListener('change',e => { console.log(e.target.files[0]); const fd = new FormData(); fd.append('img',e.target.files[0]) // 通过Ajax将图片传给后端做事器 axios({ method: 'POST', url:'http://hmajax.itheima.net/api/uploadimg', data: fd, }).then(result => { console.log(result); const imgURL = result.data.data.url; console.log(imgURL); document.querySelector('body').style.backgroundImage = `url(${imgURL})`; // 将URL存到本地 localStorage.setItem('backImg',imgURL); }) }) // 网页运行后获取url地址 const bgUrl = localStorage.getItem('backImg'); bgUrl && (document.querySelector('body').style.backgroundImage = `url(${bgUrl})`);})7.案例:个人信息设置

实现效果:

该案例可以分为四个紧张步骤:

a.信息渲染

const creator = "xiaoyu";function getProfile() { axios({ url: 'http://hmajax.itheima.net/api/settings', params:{ creator } }).then(result => { // 获取个人信息 const profile = result.data.data; // 遍历个人信息属性并显示到页面中 Object.keys(profile).forEach(key => { // 对付性别和头像须要分外处理 if(key === 'avatar'){ document.querySelector('.prew').src = profile.avatar; }else if(key === 'gender'){ const genderList = document.querySelectorAll('.gender'); genderList[profile.gender].checked = true; }else{ document.querySelector(`.${key}`).value = profile[key]; } }); });}b.头像修正

在做的这一步的时候,总是提交出错,缘故原由是没有看清api文档中的参数哀求

须要在全体FormData工具里append两个工具avatar和creator;

document.querySelector('.upload').addEventListener('change',(e) => { const fd = new FormData(); fd.append('avatar',e.target.files[0]); fd.append('creator',creator); axios({ url: "http://hmajax.itheima.net/api/avatar", method: "PUT", data:fd, }).then(result => { document.querySelector('.prew').src = result.data.data.avatar; });});c.提交表单

这里须要把稳给要提交的的工具添加一个属性,以及将字符串型的“0”转为整型的“0”

document.querySelector('.submit').addEventListener('click',() => { const form = document.querySelector('.user-form'); const newProfile = serialize(form,{hash:true,empty:true}); // 工具可以通过赋值的办法添加属性 newProfile.creator = creator; // 将字符串型的“0”转为整型的“0” newProfile.gender = +newProfile.gender; axios({ url: 'http://hmajax.itheima.net/api/settings', method: 'put', data:{ ...newProfile, } }).then(result => { console.log(result); });});d.结果提示

这里须要将提交成功的toast显示出来,如何利用Bootstrap显示提示框呢?

<div class="toast" data-bs-delay="1500"> 提示框内容</div>

const toastDom = document.querySelector('css选择器');// 创建提示框工具const toast = new bootstrap.Toast(toastDom);// 显示提示框toast.show()

实际写法:

<!-- toast提示框 --><div class="toast my-toast" data-bs-delay="1500"> <div class="toast-body"> <div class="alert alert-success info-box"> 操作成功 </div> </div></div>

const toastDom = this.document.querySelector('.my-toast');const toast = new bootstrap.Toast(toastDom);toast.show()五、XMLHttpRequest

定义:XMLHttpRequest(XHR)工具用于与做事器交互,通过XMLHttpRequest可以在不刷新页面的情形下要求特定URL,获取数据,这许可网页在不影响用户操作的情形下,更新页面的布局内容。
在AJAX编程中被大量利用;

利用XMLHttpRequest的方法:

// 创建xhr工具const xhr = new XMLHttpRequest()xhr.open('要求方法','url网址')xhr.addEventListener('loadend',() => { // 输出相应结果 console.log(xhr.response)})// 正式发送要求xhr.send()

利用axios返回的结果是工具,而原生的XHR返回的是JSON字符串,如果须要将JSON字符串转化为工具可以利用JSON.parse()的办法;

XHR如果须要携带查询参数则直接在URL里设置;

1. 案例:利用XHR获取并展示所有省份的名字

document.querySelector('.my-btn').addEventListener('click',() => { const xhr = new XMLHttpRequest(); xhr.open('get','http://hmajax.itheima.net/api/province'); xhr.addEventListener('loadend',() =>{ const data = JSON.parse(xhr.response); console.log(xhr.response); document.querySelector('.res').innerHTML = data.list.join('</br>'); }); xhr.send();})2.案例:利用XHR获取并展示制订城市的地区列表

知识拓展:对付多参数查询字符串,是可以根据工具名天生的。

// 创建URLSearchParams工具const paramsObj = new URLSearchParams({ 参数名1:值1, 参数名2:值2})// 天生指定格式的查询字符串const queryString = paramsObj.toString()// 结果:参数名1=值1&参数名2=值2

document.querySelector('.my-btn').addEventListener('click',() => { const formDom = document.querySelector('.user-form'); const form = serialize(formDom,{hash:true,empty:true}); const pname = form.province; const cname = form.city; // 获取xhr查询参数 const paramsObj = new URLSearchParams({ pname:pname, cname:cname } ); const queryURL = paramsObj.toString(); const xhr = new XMLHttpRequest(); xhr.open('get',`http://hmajax.itheima.net/api/area/?${queryURL}`); xhr.addEventListener('loadend',()=>{ // JSON.parse()将JSON字符串转为JS工具 const resObj = JSON.parse(xhr.response); const resItem = resObj.list.map(function (areaName) { return `<li class="list-group-item">${areaName}</li>` }).join(''); console.log(resItem); document.querySelector('.list-group-item').innerHTML = resItem; }); xhr.send();})3.案例:利用XHR完成数据提交的功能

利用方法:

// 见告做事器须要通报的内容类型是JSON字符串xhr.setRequestHeader('Content-Type','application/json')// JSON.stringify将JS工具转为JSON字符串const user = {key1:value1,key2:value2};const userStr = JSON.stringify(user);// 发送要求体数据xhr.send(userStr)

实际用法:

document.querySelector('.my-btn').addEventListener('click',() => { const formDom = document.querySelector('.user-form'); const form = serialize(formDom,{hash:true,empty:true}); const pname = form.province; const cname = form.city; // 获取xhr查询参数 const paramsObj = new URLSearchParams({ pname:pname, cname:cname } ); const queryURL = paramsObj.toString(); const xhr = new XMLHttpRequest(); xhr.open('get',`http://hmajax.itheima.net/api/area/?${queryURL}`); xhr.addEventListener('loadend',()=>{ const resItem = JSON.parse(xhr.response).list.map(function (areaName) { return `<li class="list-group-item">${areaName}</li>` }).join(''); console.log(resItem); document.querySelector('.list-group-item').innerHTML = resItem; }); xhr.send();})六、Promise工具

定义:Promise工具用于表示一个异步操作的终极结果值;

利用Promise的好处:

可以链式调用

用法:

// 1.创建Promise工具const p = new Promise((resove,reject) => { // 2.实行异步任务,并通报结果 setTimeout(() => { // resove('仿照成功结果'); // reject(new Error('仿照失落败结果')) },2000);})p.then(result => { // 成功 console.log(result);}).catch(error => { // 失落败 console.log(error);})1. Promise的三种状态

2.案例:利用Promise+XHR获取省份列表

需求:利用Promise管理XHR获取省份列表,并展示到页面上

实现:

// 1.创建Promise工具const p = new Promise((resolve,reject) => { // 2.实行XHR异步代码,得到省份列表 const xhr = new XMLHttpRequest(); xhr.open('get','http://hmajax.itheima.net/api/province'); xhr.addEventListener('loadend',() => { // 根据XHR返回的结果,转为工具分别给resolve和reject函数作为参数传进去 if(xhr.status >= 200 && xhr.status < 300){ resolve(JSON.parse(xhr.response)); }else{ reject(new Error(xhr.response)); } }); xhr.send();});// 3.关联成功或失落败函数做后续处理,result和error为上面传入的参数工具p.then(result => { document.querySelector('.my-p').innerHTML = result.list.join('</br>');}).catch(error => { console.dir(error); document.querySelector('.my-p').innerHTML = error.message;})3.利用XHR与Promise封装自定义的axios案例1:实现获取省份列表

需求:通过Promise和XHR实现对axios的自定义封装,完成返回省份列表的获取;

思路:

Step1:封装myAxios函数,传入config配置工具,返回Promise工具;

Step2:发起xhr要求,定义默认方法为get,定义吸收URL参数;

Step3:定义成功或失落败要求的处理程序,将传入结果工具

Step4:实际调用自封装的函数,检讨效果

function myAxios(config) { // 1. 定义myAxios函数,接管配置工具,返回Promise工具 const p = new Promise((resolve,reject) => { // 2.发起xhr要求 const xhr = new XMLHttpRequest(); xhr.open(config.method || 'get',config.url); xhr.addEventListener('loadend',() => { // 3.判断相应结果 if(xhr.status >= 200 && xhr.status < 300){ return resolve(JSON.parse(xhr.response)); }else{ return reject(new Error(xhr.response)); } }); xhr.send(); }); return p; }// 4.调用自封装的my-axiosmyAxios({ url: 'http://hmajax.itheima.net/api/province',}).then(result => { document.querySelector('.my-p').innerHTML = result.list.join('</br>');}).catch(error => { document.querySelector('.my-p').innerHTML = error.message;})案例2:实现获取地区列表

需求:修正myAxios函数,支持通报params参数,完成地区列表的查询

思路:须要考虑自定义的axios对传入的params参数的支持,可以借助URLSearchParams实现将params参数转为URL连接;

function myAxios(config) { // 1. 定义myAxios函数,接管配置工具,返回Promise工具 return new Promise((resolve,reject) => { // 2.对params进行处理,条件是有params参数 if(config.params){ const paramsObj = new URLSearchParams(config.params); const queryString = paramsObj.toString(); config.url += `?${queryString}`; } // 3.发起xhr要求 const xhr = new XMLHttpRequest(); xhr.open(config.method || 'get',config.url); xhr.addEventListener('loadend',() => { // 4.判断相应结果 if(xhr.status >= 200 && xhr.status < 300){ return resolve(JSON.parse(xhr.response)); }else{ return reject(new Error(xhr.response)); } }); xhr.send(); }); }案例3:实现注册用户功能

需求:修正myAxios函数,支持通报要求体数据,完成用户注册功能;

思路:

Step1:myAxios函数调用后,判断data选项

Step2:转换数据类型,在send方法中发送

Step3:利用自己封装的myAxios完成用户注册功能

实现:

function myAxios(config) { // 1. 定义myAxios函数,接管配置工具,返回Promise工具 return new Promise((resolve,reject) => { // 2.对params进行处理,条件是有params参数 if(config.params){ const paramsObj = new URLSearchParams(config.params); const queryString = paramsObj.toString(); config.url += `?${queryString}`; } // 3.发起xhr要求 const xhr = new XMLHttpRequest(); xhr.open(config.method || 'get',config.url); xhr.addEventListener('loadend',() => { // 4.判断相应结果 if(xhr.status >= 200 && xhr.status < 300){ return resolve(JSON.parse(xhr.response)); }else{ return reject(new Error(xhr.response)); } }); // 对data进行处理 if(config.data){ const jsonString = JSON.stringify(config.data); xhr.setRequestHeader('Content-Type','application/json') xhr.send(jsonString); }else{ xhr.send(); } }); }document.querySelector('.my-btn').addEventListener('click',() => { // 5.调用自封装的my-axios myAxios({ url: 'http://hmajax.itheima.net/api/register', method: 'post', data: { username: 'xiaoyu1927', password: '7654321' } }).then(result => { console.log(result); alert(result.message); }).catch(error => { console.dir(error); alert(error.message); })})4.案例:景象预报

步骤:

Step1:默认获取北京市景象数据,并展示;

这一步实在便是通过axios获取后端数据,并显示到html页面中,${}将网页中的元素更换为JS工具属性值,对付须要批量操作的内容,可以利用map进行映射操作;

Step2:搜索城市列表,展示;

同样是调用axios,须要给搜索框设置对input事宜的监听

const searchInput = document.querySelector('.search-city');searchInput.addEventListener('input',() => { // 获取输入框中输入的内容 const searchName = searchInput.value; // 通过axios获取城市列表 myAxios({ url: 'http://hmajax.itheima.net/api/weather/city', params:{ city:searchName, } }).then(result => { console.log(result); const cityList = result.data; const cityListStr = cityList.map(item => { return `<li class="city-item">${item.name}</li>`; }).join(''); document.querySelector('.search-list').innerHTML = cityListStr; });});

Step3:点击城市,显示对应景象数据

对搜索到的城市列表添加一个点击事宜,获取该城市的cityCode,调用前面的方法将结果渲染到页面中;

由于城市列表是动态天生的,如果须要绑定点击事宜则须要通过事宜委托(绑定父元素并通过e.target.classList.contains来获取元素)

在Step2中添加的城市列表city-item也要添加自定义属性data-code=${item.code}

return `<li class="city-item" data-code="${item.code}">${item.name}</li>`;

document.querySelector('.search-list').addEventListener('click',(e) => { // 通过事宜委托,判断点击的是否是城市item if(e.target.classList.contains('city-item')){ const cityCode = e.target.dataset.code; getWeather(cityCode) }})

终极效果:

七、同步与异步

同步:逐行实行,须要原地等待结果后,才连续向下实行;

异步:不必等待任务完成,在将来完成后触发一个回调函数;

1.回调函数地狱问题:

观点:在回调函数中嵌套回调函数,一贯嵌套下去就形成了回调函数地狱;

缺陷:耦合性严重,非常无法捕获,可读性差;

通过一个案例,理解回调函数地狱问题:

//根据省名称获取城市名称,再根据省名称和城市名称获取地区名称,axios仿照回调函数地狱问题axios({url:'http://hmajax.itheima.net/api/province'}).then(result => { const pname = result.data.list[0] document.querySelector('.province').innerHTML = pname; axios({url:'http://hmajax.itheima.net/api/city',params:{pname}}).then(result => { const cname = result.data.list[0]; document.querySelector('.city').innerHTML = cname; axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}}).then(result =>{ const areaname = result.data.list[0]; document.querySelector('.area').innerHTML = areaname; }) })})

这种嵌套问题,涌现非常是无法捕获的;

2.Promise链式调用问题

依赖then()方法会返回一个新天生的Promise工具的特性,连续串联下一环任务,直到结束;

// 将省份变量pname定义为全局变量let pname = '';axios({url:'http://hmajax.itheima.net/api/province'}).then(result => { pname = result.data.list[0]; document.querySelector('.province').innerHTML = pname; // 关键点是axios结尾返回一个新的Promise工具,这样就可以链式调用了 return axios({url:'http://hmajax.itheima.net/api/city',params:{pname}})}).then(result => { const cname = result.data.list[0]; document.querySelector('.city').innerHTML = cname; // 由于这里的pname是在兄弟浸染域中,以是将pname定义为全局变量; return axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}})}).then(result => { const area = result.data.list[0]; document.querySelector('.area').innerHTML = area;})3. 异步编程的终极办理方案-async、await

利用async和await关键字后,可以更简洁的写出基于Promise的异步辇儿动,不须要刻意地链式调用Promise;

//获取默认省市区async function getDefaultArea(){ const pObj = await axios({url:'http://hmajax.itheima.net/api/province'}); const pname = pObj.data.list[0]; const cObj = await axios({url:'http://hmajax.itheima.net/api/city',params:{pname}}); const cname = cObj.data.list[0]; const aObj = await axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}}); const aname = aObj.data.list[0]; // 授予到页面上 document.querySelector('.province').innerHTML = pname; document.querySelector('.city').innerHTML = cname; document.querySelector('.area').innerHTML = aname;}getDefaultArea();

async润色函数名表明该函数为异步函数,await表明该任务为异步任务,会原地等待后续实行完毕后将结果返回,替代then回调函数的功能;

在利用async函数和await关键字时,如何捕获缺点?答案是利用try...catch关键字;

//获取默认省市区async function getDefaultArea() { try { const pObj = await axios({ url: 'http://hmajax.itheima.net/api/province' }); const pname = pObj.data.list[0]; const cObj = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname } }); const cname = cObj.data.list[0]; const aObj = await axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname, cname } }); const aname = aObj.data.list[0]; // 授予到页面上 document.querySelector('.province').innerHTML = pname; document.querySelector('.city').innerHTML = cname; document.querySelector('.area').innerHTML = aname; } catch (error) { console.dir(error); }}getDefaultArea();4.事宜循环EventLoop

Javascript 单线程为了让耗时期码不壅塞其他代码运行,设计了事宜循环模型;

实行代码和网络异步任务,在调用栈空闲时,反复调用任务行列步队里回调函数实行机制;

为什么要有事宜循环?

由于JavaScript是单线程的,为了不壅塞JavaScript引擎,而设计实行的代码模型

事宜循环的过程:

a.实行同步代码,碰着异步代码交给宿主浏览器环境实行;

b.异步有了却果后,把回调函数放入任务行列步队排队;

c.当调用栈空闲后,返回调用任务行列步队里的回调函数;

5.宏任务与微任务

ES6之后引入了promise工具,让JS引擎也能发起异步任务:

宏任务:由浏览器环境实行的异步代码,例如JS脚本事宜、定时器、AJAX、用户交互事宜

微任务:由JS引擎环境实行的异步代码,例如Promise工具.then()回调;

Promise.then()属于微任务行列步队,优先级高于宏任务行列步队;

事宜循环经典口试题:

// 回答代码实行顺序console.log(1);setTimeout(() => { console.log(2); const p = new Promise(resolve => resolve(3)); p.then(result => console.log(result))},0);const p = new Promise(resolve => { setTimeout(() => { console.log(4); },0); resolve(5);});p.then(result => console.log(result));const p2 = new Promise(resolve => resolve(6));p2.then(result => console.log(result));console.log(7);

答案:1 7 5 6 2 3 4

6.Promise.all静态方法

语法:

const p = Promise.all([Promise工具,Promise工具,...])p.then(result => {// result结果:[Promise工具成功结果,Promise工具成功结果,...]}).catch(error => {// 第一个失落败的Promise工具,抛出的非常})案例1:同时获取北上广深四个城市的景象信息

const bjPromise = axios({url:'http://hmajax.itheima.net/api/weather',params:{city:'110100'}})const shPromise = axios({url:'http://hmajax.itheima.net/api/weather',params:{city:'310100'}})const gzPromise = axios({url:'http://hmajax.itheima.net/api/weather',params:{city:'440100'}})const szPromise = axios({url:'http://hmajax.itheima.net/api/weather',params:{city:'440300'}})const p = Promise.all([bjPromise,shPromise,gzPromise,szPromise]);p.then(result => { console.log(result); const weathers = result.map(item => { return `<li>${item.data.data.area}---${item.data.data.weather}</li>`; }).join(''); document.querySelector('.my-ul').innerHTML = weathers }).catch(error => { console.dir(error);})案例2:展示商品到分类页面上

思路:遍历所有的一级分类数据;遍历id,创建获取二级分类要求;合并所有二级分类Promise工具;等待同时成功,开始渲染页面。

axios({ url: 'http://hmajax.itheima.net/api/category/top' }).then(result => { console.log(result.data.data); // 获取二级列表的Promise工具 const subPromise = result.data.data.map(itemTop => { return axios({ url: 'http://hmajax.itheima.net/api/category/sub', params: { id: itemTop.id } }); }) // 合并二级Promise工具 const promiseAll = Promise.all(subPromise).then(result => { console.log(result); const showStr = result.map(item => { const subObj = item.data.data; return `<div class="item"> <h3>${subObj.name} <ul> ${subObj.children.map(item => { return `<li> <a href="javascript:;"> <img src=${item.picture}/> </a> <p>${item.name}</p> </li>` }).join('') } </ul> </h3> </div>` }).join(''); document.querySelector('.sub-list').innerHTML = showStr; }) })案例3:学习反馈-省市区切换

// 1.1 设置省份下拉菜单数据// 创建一个全局变量let pname = '';axios({ url: 'http://hmajax.itheima.net/api/province' }).then(provinceList => { const proinceListStr = provinceList.data.list.map(pname => { return `<option value=${pname}>${pname}</option>` }).join(''); document.querySelector('.province').innerHTML = `<option value="">省份</option>` + proinceListStr;})// 1.2 切换省份document.querySelector('.province').addEventListener('change', async e => { // 用户选中的省份 pname = e.target.value; const cityList = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname: e.target.value } }); console.log(cityList.data.list); const cityListStr = cityList.data.list.map(cname => { return `<option value=${cname}>${cname}</option>` }).join(''); document.querySelector('.city').innerHTML = `<option value="">城市</option>` + cityListStr; document.querySelector('.area').innerHTML = `<option value="">地区</option>`})// 1.3 切换城市document.querySelector('.city').addEventListener('change', async e => { // 用户选择的城市 const areaList = await axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname: pname, cname: e.target.value }}); console.log(areaList.data.list); const areaListStr = areaList.data.list.map(aname => { return `<option value=${aname}>${aname}</option>` }).join(''); document.querySelector('.area').innerHTML = `<option value="">地区</option>` + areaListStr;})// 2.网络数据并提交保存到后端document.querySelector('.submit').addEventListener('click', async () => { // 获取表单中的内容 try{ const form = document.querySelector('.info-form') const formRes = serialize(form, { hash: true, empty: true }); const res = await axios({ url: 'http://hmajax.itheima.net/api/feedback', method: 'post', data: { ...formRes } }); console.log(res); alert(res.data.message) }catch (error){ console.dir(error); alert(error.response.data.message); }})

至此,关于JavaScript AJAX干系知识就先容到这里,感谢你的阅读~

本文配套源码以及图片资源可见:https://gitee.com/yushengtan/jscode/tree/main/AJAX

标签:

相关文章

PHP实现文字转图片的代码与应用

图片处理技术在各个领域得到了广泛应用。在PHP编程中,文字转图片功能同样具有很高的实用价值。本文将针对PHP实现文字转图片的代码进...

网站建设 2025-03-02 阅读1 评论0

NAN0017探索新型纳米材料的奥秘与应用

纳米技术作为一门新兴的交叉学科,近年来在材料科学、生物医学、电子工程等领域取得了举世瞩目的成果。其中,NAN0017作为一种新型纳...

网站建设 2025-03-02 阅读5 评论0

L26368XO代码其背后的创新与突破

编程语言在各个领域发挥着越来越重要的作用。在众多编程语言中,L26368XO代码以其独特的优势,成为了业界关注的焦点。本文将深入剖...

网站建设 2025-03-02 阅读1 评论0

HTML字体背景打造个化网页设计的关键元素

网页设计已经成为现代网络传播的重要手段。在众多网页设计元素中,字体和背景的搭配尤为关键。本文将从HTML字体背景设置的角度,探讨其...

网站建设 2025-03-02 阅读1 评论0