前端AJAX与后台交互技术知识点及案例(续2)

以下笔记均为学习哔站黑马程序员AJAX视频所得!!!

AJAX作用:浏览器和服务器之间通信,动态数据交互

axios函数

先引入axios库,可在bootcdn中寻找相关js文件或者对应的script标签

    axios({url:'http://hmajax.itheima.net/api/provice'//获取数据的地址}).then(result=>{console.log(result)//一个对象console.log(result.data.list)//一个数组console.log(result.data.list.join('<br>'))//将数组中的元素以换行线隔开document.querySelector('p').innerHTML=result.data.list.join('<br>')})

 URL

  • http协议:超文本传输协议,规定浏览器和服务器之间传输数据的格式
  • 域名:标记服务器在互联网中方位(必须)
  • 资源路径:标记资源在服务器下的具体位置
        axios({url:'http://hmajax.itheima.net/api/city',// 查询参数params:{pname:'辽宁省'//最终只会提取出辽宁省下面的部分,其他省的城市不会出现}}).then(result=>{console.log(result.data.list)document.querySelector('p').innerHTML=result.data.list.join('<br>')})

URL查询参数

定义:浏览器提供给服务的额外信息,让服务器返回浏览器想要的数据

语法:http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2

作用:浏览器提供给服务器额外的信息,获取对应的数据

axios-查询参数

语法:使用axios提供的params选项

注意:axios在运行时把参数名和值,会拼接到url?参数名=值

地区查询(从服务器中获取数据)

需求:根据输入的省份名字和城市名字,查询地区并渲染列表

首先:确定URL网址和参数说明

  • 查询某个省内某个城市的所有地区:http://hmajax.itheima.net/api/area
  • 参数名:
  • pname:省份名字或直辖市名字,比如北京,福建省,辽宁省
  • cname:城市名字,比如北京市,厦门市,大连市 

完整:http://hmajax.itheima.net/api/area?pname=北京&cname=北京市

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
<style>:root {font-size: 15px;}body {padding-top: 15px;}.mb-3 {display: inline-block;}li {list-style: none;}
</style>
</head>
<body><div class="container"><form id="ediForm" class="row"><div class="mb-3 col"><label class="form-lable">省份名字</label><input type="text" value="北京" name="province" class="form-control province" placeholder="请输入省份名称" ></div><div class="mb-3 col"><label class="form-lable">城市名字</label><input type="text" value="北京市" name="city" class="form-control city" placeholder="请输入城市名称" ></div></form><button type="button" class="btn btn-primary sel-btn">查询</button><br><p>地区列表:</p><ul class="list-group"><!-- 实例地区 --><li class="list-group-item">东城区</li></ul></div><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.6.8/axios.min.js"></script><script>document.querySelector('.sel-btn').addEventListener('click',()=>{// 获取省份和城市名字let pName=document.querySelector('.province').valuelet cName=document.querySelector('.city').value// 基于axios请求地区列表数据axios({url: 'http://hmajax.itheima.net/api/area',params:{pname:pName,cname:cName//pname和cname为后端规定接口,不可随意改变,当要传进去的参数和pname,cname同名时,可以简化,params中只写pname,cname}}).then(result=>{// 把数据转成li标签 插入到页面上let list=result.data.listconsole.log(list)let theLi=list.map(areaName=>`<li class="list-group-item">${areaName}</li>`).join('')document.querySelector('.list-group').innerHTML=theLi})//theLi里面包含了很多个li标签,将其转化为字符串用join})</script>
</body>
</html>

常用请求方法:

 请求方法:对服务器资源,要执行的操作

请求方法操作
GET获取数据
POST提交数据
PUT修改数据
DELETE删除数据
PATCH修改数据(部分)

数据提交

当数据需要在服务器上保存

axios请求配置

  • url:请求的URL地址
  • method:请求的方法,GET方法可以省略(不区分大小写)
  • data:提交数据

数据提交-注册账号

  • 需求:通过axios提交用户名和密码,完成注册功能
  • 注册用户URL地址:http://hmajax.itheima.net/api/register
  • 请求方法:POST

参数名:

username 用户名(中英文和数字组成,最少8位)

password密码(最少6位)

 // 目标:点击按钮,通过axios提交用户和密码,完成注册document.querySelector('.btn').addEventListener('click',()=>{axios({url:'http://hmajax.itheima.net/api/register',// 指定请求方法method:'post',// 提交数据data:{username:'zj05090429',password:'123456'}}).then(result=>{console.log(result)})})

在上述代码中,再次注册相同的账号,会遇到报错信息,提示,账号已被占用

 

 axios错误处理

场景:再次注册相同的账号,会遇到报错处理

处理:用更直观的方式,给普通用户展示错误信息,如下:

语法:在then方法的后面,通过点语法调用catch方法,传入回调函数并定义形参

 

处理:注册案例,重复注册时通过弹框提示用户错误原因

      axios({url:'http://hmajax.itheima.net/api/register',// 指定请求方法method:'post',// 提交数据data:{username:'zj05090429',password:'123456'}}).then(result=>{// 成功console.log(result)}).catch(error=>{// 失败// 处理错误信息// console.log(error)// console.log(error.response.data.message)alert(error.response.data.message)})})

 HTTP协议-请求报文

HTTP协议:规定了浏览器发送及服务器返回内容的格式

请求报文:浏览器按照HTTP协议要求的格式,发送给服务器的内容

请求报文的组成部分有:

1.请求行:请求方法,URL,协议

2.请求头:以键值对的格式携带的附加信息,比如:Content-type

3.空行:分隔请求头,空行之后的是发送给服务器的资源

4.请求体:发送的资源

最终会将传入的数据对象转化为JSON字符串携带到请求报文中

请求报文-错误排查,可通过查看载荷中传入的数据进行分析排查

HTTP协议-响应报文

响应报文:服务器按照HTTP协议要求的格式,返回给浏览器的内容

1.相应行(状态行):协议、HTTP响应状态码、状态信息

2.相应头:以键值对的格式写到的附加信息,比如:Content-Type

3.空行:分隔响应头,空行之后的是服务器返回的资源

4.响应体:返回的资源

HTTP响应状态码:用来表明请求是否成功完成

比如:404(服务器找不到资源)

状态码说明
1xx信息
2xx 成功
3xx重定向消息
4xx客户端错误
5xx服务端错误

 接口文档

接口文档:描述接口的文章

接口:使用AJAX和服务器通讯时,请求方法,以及参数

    axios({url:'http://hmajax.itheima.net/api/login',method:'post',data:{username:'itheima007',password:'7654321'}})})

 案例-用户登录

1.点击登录时,判断用户名和密码长度

2.提交数据和服务器通信

3.提示信息

    const myAlert=document.querySelector('.alert')// 封装提示框函数,重复调用 满足提示需求// 功能:// 1.显示提示显示框// 2.不同提示文字msg,和成功绿色失败红色 issucess(true成功,false失败)// 3.过两秒之后,让提示框自动消失function alertFn(msg,isSucess){// 显示提示框myAlert.classList.add('show')// 实现细节myAlert.innerText=msgconst bgStyle=isSucess?'alert-sucess':'alert-danger'//boootstrap框架myAlert.classList.add(bgStyle)// 过两秒隐藏setTimeout(()=>{myAlert.classList.remove('show')// 避免类冲突,重置背景色myAlert.classList.remove(bgStyle)},2000)}document.querySelector('.btn-login').addEventListener('cilck',()=>{const username=document.querySelector('.username').valueconst password=document.querySelector('.password').value// 1.3判断长度if(username.length<8){alertFn('用户名必须大于8位',false)console.log('用户名必须大于等于8位')return//组织代码继续执行}if(password.length<6){alertFn('密码必须大于等于6位',false)console.log('密码必须大于等于6位')return//阻止代码继续执行}//基于axios提交用户名和密码console.log('提交数据到服务器')axios({url:'http://hmajax.itheima.net/api/login',method:'POST',data:{username,password}}).then(result=>{// console.log(result)alertFn(result.data.message,true)console.log(result.data.message)}).catch(error=>{console.log(error)console.log(error.response.data.message)//用户名或密码错误})})

form-serialize插件

作用:快速收集表单元素的值

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><form action="javascript:;" class="example-form"><input type="text" name="uname"><br><input type="text" name="pwd"><br><input type="button" value="提交" class="btn"></form><!-- 在点击提交时,使用form-serialize插件,快速收集表单元素值--><script src="./lib/form-serialize.js"></script><script>document.querySelector('.btn').addEventListener('click',()=>{/*** 使用serialize函数,快速收集表单元素的值* 参数1:要获取哪个表单的数据* 表单元素设置name属性 值会作为对象的属性名* 建议name属性的值,最好和接口文档的参数名一致* hash  设置获取数据结构*    - true JS对象(true)推荐*    - false 获取查询字符串url?后面传递的参数* empty 设置是否获取空值* - true:获取空值 推荐* - false:不获取空值* 参数2:配置对象*/const form=document.querySelector('.example-form')// const data=serialize(form,{hash:true,empty:true})const data=serialize(form,{hash:false,empty:true})console.log(data)})</script>
</body>
</html>

hash:true

hash:false

 

使用form-serialilze插件获取用户登录中表单里的数据

    const form=document.querySelector('.login-form')const data=serialize(form,{hash:true,empty:true})const {username,password}=data//解构赋值// const username = document.querySelector('.username').value// const password = document.querySelector('.password').value// console.log(username, password)

 Bootstrap弹框的使用

功能:不离开当前页面,显示单独内容,供用户操作

步骤:

  1. 引入bootstrap.css和bootstrap.js
  2. 准备弹框标签,确认结构
  3. 通过自定义属性,控制弹框的显示和隐藏、

通过属性设置,弹框的显示或隐藏(单纯显示和隐藏)

<!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>Bootstrap 弹框</title><!-- 引入bootstrap.css --><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head><body><!-- 目标:使用Bootstrap弹框1. 引入bootstrap.css 和 bootstrap.js2. 准备弹框标签,确认结构3. 通过自定义属性,控制弹框的显示和隐藏--><button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target=".my-box">显示弹框</button><!-- 弹框标签bootstrap的modal弹框,添加modal类名(默认隐藏)--><div class="modal my-box" tabindex="-1"><div class="modal-dialog"><!-- 弹框-内容 --><div class="modal-content"><!-- 弹框-头部 --><div class="modal-header"><h5 class="modal-title">Modal title</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><!-- 弹框-身体 --><div class="modal-body"><p>Modal body text goes here.</p></div><!-- 弹框-底部 --><div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button><button type="button" class="btn btn-primary">Save changes</button></div></div></div></div><!-- 引入bootstrap.js --><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js"></script>
</body></html>

通过JS设置,弹框显示或隐藏(需要额外逻辑代码)

    // 1. 创建弹框对象const modalDom = document.querySelector('.name-box')const modal = new bootstrap.Modal(modalDom)//得到了和弹框盒子对应的弹框对象 // 编辑姓名->点击->赋予默认姓名->弹框显示document.querySelector('.edit-btn').addEventListener('click', () => {document.querySelector('.username').value = '默认姓名'// 2. 显示弹框modal.show()})// 保存->点击->->获取姓名打印->弹框隐藏document.querySelector('.save-btn').addEventListener('click', () => {const username = document.querySelector('.username').valueconsole.log('模拟把姓名保存到服务器上', username)// 2. 隐藏弹框modal.hide()})

图书管理

自己的图书数据:给自己起个外号,并告诉服务器,默认会有三本书,基于这三本书做数据的增删改查

渲染图书列表

/*** 目标1:渲染图书列表*  1.1 获取数据*  1.2 渲染数据*/
const creator = '老张'
// 封装-获取并渲染图书列表函数
function getBooksList() {// 1.1 获取数据axios({url: 'http://hmajax.itheima.net/api/books',params: {// 外号:获取对应数据creator}}).then(result => {// console.log(result)const bookList = result.data.dataconsole.log(bookList)// 1.2 渲染数据const htmlStr = bookList.map((item, index) => {return `<tr><td>${index + 1}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td data-id=${item.id}><span class="del">删除</span><span class="edit">编辑</span></td></tr>` //映射到数组的每个元素 并返回修改过的新数组}).join('')// console.log(htmlStr)document.querySelector('.list').innerHTML = htmlStr})
}

新增图书

/*** 目标2:新增图书*  2.1 新增弹框->显示和隐藏*  2.2 收集表单数据,并提交到服务器保存*  2.3 刷新图书列表*/
// 2.1 创建弹框对象
const addModalDom = document.querySelector('.add-modal')
const addModal = new bootstrap.Modal(addModalDom)//利用js代码来隐藏和显示
// 保存按钮->点击->隐藏弹框
document.querySelector('.add-btn').addEventListener('click', () => {// 2.2 收集表单数据,并提交到服务器保存const addForm = document.querySelector('.add-form')const bookObj = serialize(addForm, { hash: true, empty: true })// console.log(bookObj)// 提交到服务器axios({url: 'http://hmajax.itheima.net/api/books',method: 'POST',data: {...bookObj,//它用于将 bookObj 中的所有可迭代属性展开到新的对象中。这意味着新对象将包含 bookObj 中的所有键值对。creator}}).then(result => {// console.log(result)// 2.3 添加成功后,重新请求并渲染图书列表getBooksList()// 重置表单addForm.reset()// 隐藏弹框addModal.hide()})
})

删除图书

/*** 目标3:删除图书*  3.1 删除元素绑定点击事件->获取图书id*  3.2 调用删除接口*  3.3 刷新图书列表*/
// 3.1 删除元素->点击(事件委托)
document.querySelector('.list').addEventListener('click', e => {// 获取触发事件目标元素// console.log(e.target)// 判断点击的是删除元素if (e.target.classList.contains('del')) {// console.log('点击删除元素')// 获取图书id(自定义属性id)const theId = e.target.parentNode.dataset.id// console.log(theId)// 3.2 调用删除接口axios({url: `http://hmajax.itheima.net/api/books/${theId}`,method: 'DELETE'}).then(() => {// 3.3 刷新图书列表getBooksList()})}
})

编辑图书

/*** 目标4:编辑图书*  4.1 编辑弹框->显示和隐藏*  4.2 获取当前编辑图书数据->回显到编辑表单中*  4.3 提交保存修改,并刷新列表*/
// 4.1 编辑弹框->显示和隐藏
const editDom = document.querySelector('.edit-modal')
const editModal = new bootstrap.Modal(editDom)
// 编辑元素->点击->弹框显示
document.querySelector('.list').addEventListener('click', e => {// 判断点击的是否为编辑元素if (e.target.classList.contains('edit')) {// 4.2 获取当前编辑图书数据->回显到编辑表单中const theId = e.target.parentNode.dataset.idaxios({url: `http://hmajax.itheima.net/api/books/${theId}`}).then(result => {const bookObj = result.data.data// document.querySelector('.edit-form .bookname').value = bookObj.bookname// document.querySelector('.edit-form .author').value = bookObj.author// 数据对象“属性”和标签“类名”一致// 遍历数据对象,使用属性去获取对应的标签,快速赋值const keys = Object.keys(bookObj) // ['id', 'bookname', 'author', 'publisher']keys.forEach(key => {document.querySelector(`.edit-form .${key}`).value = bookObj[key]})})editModal.show()}
})
// 修改按钮->点击->隐藏弹框
document.querySelector('.edit-btn').addEventListener('click', () => {// 4.3 提交保存修改,并刷新列表const editForm = document.querySelector('.edit-form')const { id, bookname, author, publisher } = serialize(editForm, { hash: true, empty: true})// 保存正在编辑的图书id,隐藏起来:无需让用户修改// <input type="hidden" class="id" name="id" value="84783">axios({url: `http://hmajax.itheima.net/api/books/${id}`,method: 'PUT',//修改data: {bookname,author,publisher,creator}}).then(() => {// 修改成功以后,重新获取并刷新列表getBooksList()// 隐藏弹框editModal.hide()})
})

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>案例-图书管理</title><!-- 字体图标 --><link rel="stylesheet" href="https://at.alicdn.com/t/c/font_3736758_vxpb728fcyh.css"><!-- 引入bootstrap.css --><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet"><!-- 核心样式 --><link rel="stylesheet" href="./css/index.css">
</head><body><!-- 主体区域 --><div class="container"><!-- 头部标题和添加按钮 --><div class="top"><h3>图书管理</h3><button type="button" class="btn btn-primary plus-btn" data-bs-toggle="modal" data-bs-target=".add-modal"> + 添加</button></div><!-- 数据列表 --><table class="table"><thead class="table-light"><tr><th style="width: 150px;">序号</th><th>书名</th><th>作者</th><th>出版社</th><th style="width: 180px;">操作</th></tr></thead><tbody class="list"><tr><td>1</td><td>JavaScript程序设计</td><td>马特·弗里斯比</td><td>人民邮电出版社</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr></tbody></table></div><!-- 新增-弹出框 --><div class="modal fade add-modal"><!-- 中间白色区域 --><div class="modal-dialog"><div class="modal-content"><div class="modal-header top"><span>添加图书</span><button type="button" class="btn-close" aria-label="Close" data-bs-dismiss="modal"></button></div><div class="modal-body form-wrap"><!-- 新增表单 --><form class="add-form"><div class="mb-3"><label for="bookname" class="form-label">书名</label><input type="text" class="form-control bookname" placeholder="请输入书籍名称" name="bookname"></div><div class="mb-3"><label for="author" class="form-label">作者</label><input type="text" class="form-control author" placeholder="请输入作者名称" name="author"></div><div class="mb-3"><label for="publisher" class="form-label">出版社</label><input type="text" class="form-control publisher" placeholder="请输入出版社名称" name="publisher"></div></form></div><div class="modal-footer btn-group"><button type="button" class="btn btn-primary" data-bs-dismiss="modal"> 取消 </button><button type="button" class="btn btn-primary add-btn"> 保存 </button></div></div></div></div><!-- 编辑-弹出框 --><div class="modal fade edit-modal"><!-- 中间白色区域 --><div class="modal-dialog"><div class="modal-content"><div class="modal-header top"><span>编辑图书</span><button type="button" class="btn-close" aria-label="Close" data-bs-dismiss="modal"></button></div><div class="modal-body form-wrap"><!-- 编辑表单 --><form class="edit-form"><input type="hidden" class="id" name="id"><div class="mb-3"><label for="bookname" class="form-label">书名</label><input type="text" class="form-control bookname" placeholder="请输入书籍名称" name="bookname"></div><div class="mb-3"><label for="author" class="form-label">作者</label><input type="text" class="form-control author" placeholder="请输入作者名称" name="author"></div><div class="mb-3"><label for="publisher" class="form-label">出版社</label><input type="text" class="form-control publisher" placeholder="请输入出版社名称" name="publisher"></div></form></div><div class="modal-footer btn-group"><button type="button" class="btn btn-primary" data-bs-dismiss="modal"> 取消 </button><button type="button" class="btn btn-primary edit-btn"> 修改 </button></div></div></div></div><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.0/axios.min.js"></script><script src="./lib/form-serialize.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/js/bootstrap.min.js"></script><!-- 核心逻辑 --><script src="./js/index.js"></script>
</body></html>

图片上传

  1. 获取图片文件对象
  2. 使用FormData携带图片文件
  3. 提交表单数据到服务器,使用图片url地址
<!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>图片上传</title>
</head><body><!-- 文件选择元素 --><input type="file" class="upload"><img src="" alt="" class="my-img"><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>/*** 目标:图片上传,显示到网页上*  1. 获取图片文件*  2. 使用 FormData 携带图片文件*  3. 提交到服务器,获取图片url网址使用*/// 文件选择元素->change改变事件document.querySelector('.upload').addEventListener('change', e => {// 1. 获取图片文件console.log(e.target.files[0])// 2. 使用 FormData 携带图片文件const fd = new FormData()fd.append('img', e.target.files[0])// 3. 提交到服务器,获取图片url网址使用axios({url: 'http://hmajax.itheima.net/api/uploadimg',method: 'POST',data: fd}).then(result => {console.log(result)// 取出图片url网址,用img标签加载显示const imgUrl = result.data.data.urldocument.querySelector('.my-img').src = imgUrl})})</script>
</body></html>

input file类型的change事件

input元素的file类型允许用户从他们的设备上选择一个或多个文件。当用户选择了文件(或者修改了已选择的文件)后,change事件就会被触发。这意味着如果用户通过点击文件输入框并选择了文件,或者拖拽文件到文件输入区域,change事件监听器就会执行。

FormData

FormData 是一个 JavaScript 内建对象,它主要用于构造一组键值对的数据集合,用以发送 HTTP 请求。这个对象特别适用于发送表单数据,无论是作为 AJAX 请求还是使用 Fetch API 发送数据到服务器,尤其是当涉及到文件上传时。以下是关于 FormData 的一些关键特点和使用方法:

特点:

  1. 自动构建请求体FormData 会根据给定的数据自动构建合适的请求体(Content-Type),这使得它在处理表单数据时非常方便,尤其是当涉及文件上传时,它会正确地设置 multipart/form-data 编码。
  2. 兼容性:支持现代浏览器,包括 IE10+,对于旧版浏览器,可能需要polyfill。
  3. 无需序列化:与传统的 XMLHttpRequest 发送表单数据时需要手动序列化不同,FormData 自动处理这一过程。
  4. 文件上传:非常适合用于文件上传,因为它能够处理二进制数据。

基本用法:

创建实例:
let formData = new FormData();
添加数据:
// 添加文本字段
formData.append('key', 'value');// 添加文件
let file = document.querySelector('input[type=file]').files[0];
formData.append('file', file);// 添加多个值到同一个键
formData.append('multiValueKey', 'value1');
formData.append('multiValueKey', 'value2');
发送请求:

使用 XMLHttpRequestfetch 发送数据:

// 使用 XMLHttpRequest
let xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload', true);
xhr.send(formData);// 使用 fetch
fetch('/api/upload', {method: 'POST',body: formData
})
then(response => response.json())
then(data => console.log(data))
catch(error => console.error('Error:', error));

注意事项:

  • 当从表单直接创建 FormData 实例时,表单中的所有字段(包括文件输入)会被自动添加到 FormData 中。
  • 可以通过 formData.get(key)formData.getAll(key)formData.has(key)formData.set(key, value)formData.delete(key) 等方法来操作数据。
  • 如果需要获取 FormData 中的所有键值对,可以使用 formData.entries() 方法配合迭代器遍历。

FormData 是处理表单数据和文件上传的强大工具,极大地简化了从前复杂的 AJAX 请求处理过程。

 更换网页背景图片

1.选择图片上传,设置body背景

2.上传成功时,保存url网址

3.网页运行后,获取url网址使用

/*** 目标:网站-更换背景*  1. 选择图片上传,设置body背景*  2. 上传成功时,"保存"图片url网址*  3. 网页运行后,"获取"url网址使用* */
//选择对应的input框绑定change事件
document.querySelector('.bg-ipt').addEventListener('change', e => {// 1. 选择图片上传,设置body背景console.log(e.target.files[0])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 => {const imgUrl = result.data.data.urldocument.body.style.backgroundImage = `url(${imgUrl})`// 2. 上传成功时,"保存"图片url网址localStorage.setItem('bgImg', imgUrl)})
})// 3. 网页运行后,"获取"url网址使用
const bgUrl = localStorage.getItem('bgImg')
console.log(bgUrl)
// 本地有背景图才设置
bgUrl && (document.body.style.backgroundImage = `url(${bgUrl})`)

个人信息设置

步骤:

1.信息渲染

2.头像修改

3.提交表单

4.结果提示

信息渲染

自己的用户信息:给自己起个外号,并告诉服务器,获取对应的用户信息

/*** 目标1:信息渲染*  1.1 获取用户的数据*  1.2 回显数据到标签上* */
const creator = '播仔'
// 1.1 获取用户的数据
axios({url: 'http://hmajax.itheima.net/api/settings',params: {creator}
}).then(result => {const userObj = result.data.data// 1.2 回显数据到标签上Object.keys(userObj).forEach(key => {if (key === 'avatar') {// 赋予默认头像document.querySelector('.prew').src = userObj[key]} else if (key === 'gender') {//gender和头像不可通过value来改变,只有表单元素才可通过foreach来改变// 赋予默认性别// 获取性别单选框:[男radio元素,女radio元素]const gRadioList = document.querySelectorAll('.gender')// 获取性别数字:0男,1女const gNum = userObj[key]// 通过性别数字,作为下标,找到对应性别单选框,设置选中状态gRadioList[gNum].checked = true} else {// 赋予默认内容document.querySelector(`.${key}`).value = userObj[key]}})
})

头像修改

/*** 目标2:修改头像*  2.1 获取头像文件*  2.2 提交服务器并更新头像* */
// 文件选择元素->change事件
document.querySelector('.upload').addEventListener('change', e => {// 2.1 获取头像文件console.log(e.target.files[0])const fd = new FormData()fd.append('avatar', e.target.files[0])fd.append('creator', creator)// 2.2 提交服务器并更新头像axios({url: 'http://hmajax.itheima.net/api/avatar',method: 'PUT',data: fd}).then(result => {const imgUrl = result.data.data.avatar// 把新的头像回显到页面上document.querySelector('.prew').src = imgUrl})
})

提交表单(信息修改)

结果提示

给div盒子添加类名toast,会出现提示框

/*** 目标4:结果提示*  4.1 创建toast对象*  4.2 调用show方法->显示提示框*/
// 保存修改->点击
document.querySelector('.submit').addEventListener('click', () => {// 3.1 收集表单信息const userForm = document.querySelector('.user-form')const userObj = serialize(userForm, { hash: true, empty: true })userObj.creator = creator// 性别数字字符串,转成数字类型userObj.gender = +userObj.genderconsole.log(userObj)// 3.2 提交到服务器保存axios({url: 'http://hmajax.itheima.net/api/settings',method: 'PUT',data: userObj//aixos会自动将对象转化为JSON字符串}).then(result => {// 4.1 创建toast对象const toastDom = document.querySelector('.my-toast')const toast = new bootstrap.Toast(toastDom)// 4.2 调用show方法->显示提示框toast.show()})
})

AJAX原理 - XMLHttpRequest

定义:XMLHttpRequest(XHR)对象用于与服务器进行交互,通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL,获取数据,这允许网页在不影响用户操作的情况下,更新页面的局部内容,XMLHttpRequest在AJAX编程中被大量使用

关系:axios内部采用XMLHttpRequest与服务器进行交互

好处:掌握使用XHR与服务器进行数据交互,了解axios内部原理

使用XMLHttpRequest

需求:获取并展示所有省份名字

    /*** 目标:使用XMLHttpRequest对象与服务器通信*  1. 创建 XMLHttpRequest 对象*  2. 配置请求方法和请求 url 地址*  3. 监听 loadend 事件,接收响应结果*  4. 发起请求*/// 1. 创建 XMLHttpRequest 对象const xhr = new XMLHttpRequest()// 2. 配置请求方法和请求 url 地址xhr.open('GET', 'http://hmajax.itheima.net/api/province')// 3. 监听 loadend 事件,接收响应结果,loadend无论成功还是失败,都会执行后面的函数xhr.addEventListener('loadend', () => {console.log(xhr.response)const data = JSON.parse(xhr.response)console.log(data.list.join('<br>'))document.querySelector('.my-p').innerHTML = data.list.join('<br>')})// 4. 发起请求xhr.send()

XHR使用步骤:

  • 创建XHR对象
  • 调用open方法,设置url和请求方法
  • 监听loadend事件,接收结果
  • 调用send方法,发起请求

 XMLHttpRequest- 查询参数

定义:浏览器提供给服务器的额外信息,让服务器返回浏览器想要的数据

语法:http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2

    /*** 目标:使用XHR携带查询参数,展示某个省下属的城市列表*/const xhr = new XMLHttpRequest()xhr.open('GET', 'http://hmajax.itheima.net/api/city?pname=辽宁省')xhr.addEventListener('loadend', () => {console.log(xhr.response)const data = JSON.parse(xhr.response)console.log(data)document.querySelector('.city-p').innerHTML = data.list.join('<br>')})xhr.send()

地区查询

需求:输入省份和城市名字,查询地区列表

请求地址:http://hmajax.itheima.net/api/area?参数名=值1&参数名=值2

    /*** 目标: 根据省份和城市名字, 查询对应的地区列表*/// 1. 查询按钮-点击事件document.querySelector('.sel-btn').addEventListener('click', () => {// 2. 收集省份和城市名字const pname = document.querySelector('.province').valueconst cname = document.querySelector('.city').value// 3. 组织查询参数字符串const qObj = {pname,cname}// 查询参数对象 -> 查询参数字符串const paramsObj = new URLSearchParams(qObj)const queryString = paramsObj.toString()console.log(queryString)// 4. 使用XHR对象,查询地区列表const xhr = new XMLHttpRequest()xhr.open('GET', `http://hmajax.itheima.net/api/area?${queryString}`)xhr.addEventListener('loadend', () => {console.log(xhr.response)const data = JSON.parse(xhr.response)console.log(data)const htmlStr = data.list.map(areaName => {return `<li class="list-group-item">${areaName}</li>`}).join('')console.log(htmlStr)document.querySelector('.list-group').innerHTML = htmlStr})xhr.send()})

XMLHttpRequest - 数据提交

需求:通过XHR提交用户名和密码,完成注册功能

核心:

  • 请求头设置Content - Type:application/json
  • 请求体携带JSON字符串
  <button class="reg-btn">注册用户</button><script>/*** 目标:使用xhr进行数据提交-完成注册功能*/document.querySelector('.reg-btn').addEventListener('click', () => {const xhr = new XMLHttpRequest()xhr.open('POST', 'http://hmajax.itheima.net/api/register')xhr.addEventListener('loadend', () => {console.log(xhr.response)})// 设置请求头-告诉服务器内容类型(JSON字符串)xhr.setRequestHeader('Content-Type', 'application/json')// 准备提交的数据const userObj = {username: 'itheima007',password: '7654321'}const userStr = JSON.stringify(userObj)// 设置请求体,发起请求xhr.send(userStr)})</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/10786.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot基于微信小程序的星座配对(源码)

博主介绍&#xff1a;✌程序员徐师兄、10年大厂程序员经历。全网粉丝12W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447…

【Shell】shell编程之循环语句

目录 1.for循环 例题 2.while循环 例题 3.until循环 1.for循环 读取不同的变量值&#xff0c;用来逐个执行同一组命令 for 变量 in 取值列表 do 命令序列 done [rootlocalhost ~]# for i in 1 2 3 > do > echo "第 $i 次跳舞" > done 第 1 次跳舞 第 …

Vue3实战笔记(02)--- 使用VUETIFY图标字体

文章目录 前言一、Material Design 图标二、Font Awesome三、混合方式使用总结 前言 Vuetify 开箱即支持 4 种流行的图标字体库—— Material Design Icons&#xff0c;Material Icons&#xff0c;Font Awesome 4 和 Font Awesome 5。今天为项目安装喜欢的图标。 一、Material…

AI虚拟伴侣方案

打造类似Character AI的产品,现成的训练好的模型方案,适合做陪伴型虚拟女友等项目,近期看到的最佳项目: 1、项目背景: (1)项目动机:角色扮演LLM是AI的第二大消费用例,但通常被开源社区忽视。 (2)行业现状:缺乏与https://character.ai/提供的角色扮演LLM相对应的…

msvcp140dll怎么修复,分享5种有效的解决方法

MSVCP140.dll文件丢失这一现象究竟是何缘由&#xff0c;又会引发哪些令人头疼的问题呢&#xff1f;在探索这个问题的答案之前&#xff0c;我们先来深入了解这个神秘的DLL文件。MSVCP140.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它扮演着至关重要的…

创新指南 | 生成式AI如何引领企业创新未来?

2023年麦肯锡全球数字战略调查了1000多名受访者&#xff0c;发现&#xff1a;建立创新文化的组织与它们应用包括生成式AI在内的最新数字技术提高产出的能力之间有着惊人的强关联。 本文探讨了顶尖创新企业采取的五项行动&#xff0c;使它们与同行之间拉开距离&#xff0c;并在使…

【Go语言初探】(一)、Linux开发环境建立

一、操作系统选择 选择在Windows 11主机上运行的CentOS 7 Linux 虚拟机&#xff0c;虚拟化平台为VMWare Workstation. 二、安装Go语言环境 访问Go语言官网&#xff0c;选择Linux版本下载&#xff1a; 解压&#xff1a; tar -xvf go1.22.3.linux-amd64.tar.gz检验安装结果&…

DE2-115串口通信

目录 一、 内容概要二、 Hello Nios-II2.1 Nios-II编程2.1.1 硬件Ⅰ 搭建环境Ⅱ 编写代码 2.1.2 软件2.1.3 烧录Ⅰ硬件Ⅱ 软件 2.2 verilog编程 三、 心得体会 一、 内容概要 分别用Verilog和Nios软件编程, 实现DE2-115开发板串口输出“Hello Nios-II”字符到笔记本电脑串口助…

C++ list介绍(迭代器失效)

一、常用接口 reverse逆置 sort排序&#xff08;默认升序&#xff09; 仿函数greater<int> merge合并&#xff0c;可以全部合并&#xff0c;也可以一部分合并 unique&#xff1a;去重&#xff08;先排序&#xff0c;再去重&#xff09; remove&#xff1a;删除e值&#…

超详细的胎教级Stable Diffusion使用教程(五)

这套课程分为五节课&#xff0c;会系统性的介绍sd的全部功能和实操案例&#xff0c;让你打下坚实牢靠的基础 一、为什么要学Stable Diffusion&#xff0c;它究竟有多强大&#xff1f; 二、三分钟教你装好Stable Diffusion 三、小白快速上手Stable Diffusion 四、Stable dif…

Linux中每当执行‘mount’命令(或其他命令)时,自动激活执行脚本:输入密码,才可以执行mount

要实现这个功能&#xff0c;可以通过创建一个自定义的mount命令的包装器&#xff08;wrapper&#xff09;来完成。这个包装器脚本会首先提示用户输入密码&#xff0c;如果密码正确&#xff0c;则执行实际的mount命令。以下是创建这样一个包装器的步骤&#xff1a; 创建一个名为…

Elasticsearch入门基础和集群部署

Elasticsearch入门基础和集群部署 简介基础概念索引&#xff08;Index&#xff09;类型&#xff08;Type&#xff09;&#xff08;逐步弃用&#xff09;文档&#xff08;Document&#xff09;字段&#xff08;Field&#xff09;映射&#xff08;Mapping&#xff09;分片&#x…

第十二届蓝桥杯省赛真题 Java A 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: 相乘试题 B: 直线试题 C : \mathrm{C}: C: 货物摆放试题 D: 路径试题 E: 回路计数试题 F : \mathrm{F}: F: 最少砝码试题 G: 左孩子右兄弟试题 H : \mathrm{H}: H: 异或数列试题 I \mathbf{I} I 双向排序试题 J : \mathrm{J}: J: 分…

Promise.all和 race

Promise.all() all方法可以完成并行任务&#xff0c; 它接收一个数组&#xff0c;数组的每一项都是一个promise对象。返回值&#xff1a; 成功时&#xff1a;当数组中所有的promise的状态都达到resolved的时候&#xff0c;就返回包含所有 Promise 结果的数组&#xff0c;并且…

Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV

OpenCV是大型的Third party 计算机视觉库&#xff0c;在开发中会经常用到&#xff0c;本篇记录一下 在Ubuntu系统上安装和配置OpenCV&#xff0c;并使用C/C调用OpenCV 关于VS Code配置C/C开发环境的部分&#xff0c;见之前的博文 Linux/Ubuntu系统下使用VS Code配置C/C开发环境…

shell进阶之计算编译前后时间(十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

代码+视频,R言语处理数据中的缺失值

在SCI论文中&#xff0c;我们不可避免和缺失数据打交道&#xff0c;特别是在回顾性研究&#xff0c;对于缺失的协变量&#xff08;就是混杂因素&#xff09;&#xff0c;我们可以使用插补补齐数据&#xff0c;但是对于结局变量和原因变量的缺失&#xff0c;我们不能这么做。部分…

mysql设置远程访问权限,允许其他IP访问

文章目录 更改mysql配置文件登录mysql 更改mysql配置文件 查找.ini或者.cnf文件 更改bind-address为0.0.0.0 [mysqld] character-set-serverutf8mb4 bind-address0.0.0.0 default-storage-engineINNODB [mysql] default-character-setutf8mb4 [client] default-character-s…

数据分析思维——数据埋点笔记,以电商为例

数据埋点 数据分析前提是有数据&#xff0c;数据从哪里来&#xff0c;要选择采集哪些数据都需要考虑。如某些app上的商品推荐&#xff0c;是基于哪些信息来预判的呢&#xff1f;因此作为数据分析师有必要系统的了解用户行为到用户数据的整个过程 何为数据埋点 每当用户在客户端…

【GlobalMapper精品教程】079:投影坐标系转地理坐标系(UTM转WGS1984/2000)

文章目录 一、矢量UTM转WGS1984/20001. UTM转WGS19842. UTM转CGCS2000二、栅格UTM转WGS1984/2000一、矢量UTM转WGS1984/2000 加载配套实验数据(data079.rar)中的矢量数据,如下所示: 查看源坐标系:双击图层的,图层投影选项卡,为UTM投影,Zone48N。 设置系统坐标系:点击…