前端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.hqwc.cn/news/692226.html

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

相关文章

厉害了!12秒将百万数据通过EasyExcel导入MySQL数据库中

一、写在开头 我们在上一篇文章中提到了通过EasyExcel处理Mysql百万数据的导入功能&#xff08;一键看原文&#xff09;&#xff0c;当时我们经过测试数据的反复测验&#xff0c;100万条放在excel中的数据&#xff0c;4个字段的情况下&#xff0c;导入数据库&#xff0c;平均耗…

树莓派点亮FPGA小灯

树莓派点亮FPGA小灯 引言&#xff1a; ​ 本次实验的目的是通过树莓派和FPGA之间的串口通信&#xff0c;控制FPGA开发板上的小灯。实验将展示如何使用树莓派发送特定的字符信号&#xff0c;通过串口传输至FPGA&#xff0c;并在FPGA上实现逻辑解析&#xff0c;以点亮指定的小灯。…

[240512] x-cmd 发布 v0.3.6: (se,wkp,ddgo...)x( kimi,gemini,gpt...)

目录 x-cmd 发布 v0.3.6新增了 jina 模块新增了 ddgo 模块新增了 se 模块wkp 模块新增了 writer 模块cosmo 模块 x-cmd 发布 v0.3.6 本次版本的最新引入的功能都是目的为了进一步探索 LLM 的使用。 本版本的改进分为两类&#xff1a;资讯类模块&#xff08;Wikipedia&#xf…

李廉洋:5.12黄金原油下周一行情分析,必看策略。

黄金消息面分析&#xff1a;美国4月份潜在通胀可能出现6个月来的首次放缓&#xff0c;在一系列意外上涨之后&#xff0c;物价压力有望再次开始缓解。核心CPI预计环比上涨0.3%&#xff0c;此前三个月的涨幅均为0.4%&#xff0c;同比预计将上涨3.6%&#xff0c;尽管这一增幅将是三…

rust开发web服务器框架,github排名对比

Rocket Star最多的框架 github仓库地址&#xff1a;GitHub - rwf2/Rocket: A web framework for Rust. Rocket 是一个针对 Rust 的异步 Web 框架&#xff0c;重点关注可用性、安全性、可扩展性和速度。 Axum 异步运行时 githuh仓库地址&#xff1a;GitHub - tokio-rs/axum: …

能源效率:未来可持续发展的全球当务之急

当前全球正面临着严重的能源与气候危机&#xff0c;能源消耗不断增长导致环境污染、气候变化等问题日益严重。在这一背景下&#xff0c;提高能源效率成为了当务之急。今天&#xff0c;我们来简要探讨一下能源效率在全球可持续发展中的重要性&#xff0c;重点关注建筑物能源效率…

C语言——文件相关操作补充

一、文件读取结束的判定 当我们使用例如fgetc、fgets、fscanf、fread等函数来读取文件内容时&#xff0c;我们可能遇到需要判断文件读取的结束&#xff0c;一般情况下都是通过这些函数的返回值来判断文件读取是否结束。 1、fgetc 返回读取的字符的ASCII值&#xff0c;如果读…

微信授权登录02-移动端

目录 ## 前言 1.准备工作 1.1 网站域名 1.2 微信公众号 2.授权登录开发 2.1 前端开发 2.1.1 调起微信授权页面 ## 调起微信授权页面效果图 2.1.2 用户允许授权后回调处理 2.2 后端开发 2.2.1 根据code查询用户信息 2.2.2 自动注册登录 ## 后记 ## 前言 上一篇写…

使用Flask构建POST请求的Web应用

文章目录 准备工作创建路由处理POST请求创建表单页面运行应用结论 在Web开发中&#xff0c;处理POST请求是一项常见任务&#xff0c;特别是在构建表单提交、用户注册和数据提交等功能时。Flask是一个简单而强大的Python Web框架&#xff0c;它提供了方便的工具来处理HTTP请求&a…

bash tab 补全报错 bash: syntax error near unexpected token `(‘

使用 vim 编辑文件时&#xff0c;敲下 vim xxx 后&#xff0c;再键入 tab 键报进行补全报错 bash: syntax error near unexpected token (. 打开 bash 的命令执行详情 set -v 定位到具体的代码&#xff1a; 显然&#xff0c;代码位于 bash 补全的逻辑当中。 定位代码具体的…

大学生体质测试|基于Springboot+vue的大学生体质测试管理系统设计与实现(源码+数据库+文档)

大学生体质测试管理系统 目录 基于Springboot&#xff0b;vue的大学生体质测试管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 4教师功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算…