Ajax

Ajax

一、回顾 和 目标

重点内容回顾 和 今天的学习目标

回顾:

  1. http://ajax-api.itheima.net:80/public/images/0.webp

    1. 协议:http
    2. 主机:ajax-api.itheima.net
    3. 端口:80
    4. 资源路径:/public/images/0.webp
  2. ajax的作用?

    1. 不刷新页面和 服务器通讯
  3. 接口

    1. 文档-->接口文档

      1. ajax和服务器通讯-->调用接口,调接口
    2. ajax调用接口类似于调用后端写的方法

  4. axios

    1. 是个什么?
      1. 请求库,基于ajax封装
    2. get请求?
      1. axios.get(url,{params:{key:value}})--->url?key=value&key2=value2
    3. post请求?
      1. axios.post(url,{key:value})
  5. ajax开发的核心步骤:

    1. 请求
      1. 什么时候发
      2. 是否需要携带数据
      3. 发请求之前有什么逻辑
    2. 响应
      1. 如何获取数据?then
      2. 获取到数据之后的逻辑
        1. 弹框提示用户
        2. 渲染页面-->arr-map-->htmlArr-join->htmlString-->innerHTML(appendChild)

目标:

  1. Form表单+ajax
  2. 几种不同提交数据的格式

二、axios-config模式

除了昨天的.get,.post,axios也支持传入对象的形式发送请求,咱们来研究一下

传送门:axios-api

传送门:请求配置

概念:

  1. 通过属性的方式设置请求需要的内容
    1. 地址
    2. 方法
    3. 参数
    4. ....

步骤:

  1. 根据文档确认调用方法并测试
  2. get请求+传参
    1. 测试机器人接口
  3. post请求+传参
    1. 测试登录接口

axios-config模式

这一节咱们学习了axios一种新的发请求方法,现在发请求可以用几种不同的写法啦,功能上没啥区别:

  1. 开发中用哪个?

    1. axios({})-->
      1. 不需要记忆不同的方法
      2. 只需要记忆配置即可,一个方法即可发送各种不同的请求
      3. 推荐用法
    2. axios.get/.post
  2. 选项,配置在哪里查询?是否需要背下来?

    1. 看官方文档
    2. 不需要,随用随查即可

需求:

  1. 打开页面获取所有数据并渲染
    1. 参考思路:
    2. 什么时候发请求?
      1. window.onload
    3. 是否要携带数据?
      1. 不需要,获取所有英雄
    4. 获取到数据之后的逻辑?
      1. 渲染到页面上
  2. 输入内容按下回车,检索数据并渲染
    1. 什么时候发请求?
      1. keyup, e.keyCode===13
    2. 是否要携带数据?
      1. 需要,携带value
    3. 获取到数据之后的逻辑
      1. 渲染到页面上
  3. 搞定之后简化代码

三、form表单

form表单-原生提交数据

对于有多个数据需要提交的场景,一般会结合form表单来完成,原生form表单可以用来提交数据(目前基本不这么用,了解即可),咱们来测试一下

传送门:MDN-form表单

适用场景

  • form表单常用于网页中需要收集多个数据的位置,比如,登录,注册,信息设置等。。

常见组成:

  1. 表单元素:form标签
  2. 表单输入元素:常见的有inputtextareaselect...
  3. 提交按钮:
    1. button type="submit"
      1. type默认值为submit,可以省略
    2. input type=submit
<form action="http://ajax-api.itheima.net/api/data" method="post">
  <input type="text"  placeholder="请输入用户名" />
  <br />
  <input type="text" placeholder="请输入喜欢的食物" />
  <br />
  <input type="textarea" placeholder="请输入个性签名" />
  <br />
  <button type="submit">提交</button>
</form>

原生数据提交

  1. form标签设置:
    1. action:接口地址
    2. method:请求方法
  2. 表单输入元素设置:
    1. name:提交到服务器数据的key(参数)
  • 基于提供的接口测试并验证几个问题:
    • 服务器是否获取到了form表单提交的数据?
    • 表单输入元素的name的作用?
    • 页面重新加载了吗?
    • 请求体中确认提交的数据格式
  • 测试用接口:传送门

form表单-原生提交数据

原生的form表单如何提交数据,写法上不需要掌握,需要记住如下几点:

  1. form表单是否可以提交数据到服务器?

    1. 可以的
  2. 直接用form表单提交数据,和用ajax最大的区别是?

    1. 页面会刷新,目前基本不用他

form表单-ajax提交数据

直接用form表单提交数据带来的用户体验并不好,咱们这一节通过ajax来提交数据

步骤:

  1. 阻止事件的默认行为(下面两者取其一):
    1. button的点击事件
    2. formsubmit事件
    3. 目的:避免form提交数据
  2. axios根据文档设置,地址,方法,参数..
  3. 提交数据

测试:

  1. 测试2种事件绑定语法

    1. 表单的submit事件
    2. buttonclick事件
  2. 测试数据提交

form表单-ajax提交数据

如何将表单和ajax结合起来,核心代码就是获取表单中输入元素的value值,并通过ajax提交:

  1. ajax提交form原生提交最大的区别是?

    1. 页面是否刷新
      1. ajax不刷新
      2. form刷新-->目前基本不用
  2. 为什么需要阻止formsubmitbuttonclick事件?

    1. 不阻止,页面会刷新

    2. e.preventDefault()->阻止默认行为

      1. a默认行为-->跳转
      2. e.preventDefault()
      3. a点击不跳转
    3. 表单默认会提交数据

注意:

  1. axios()的属性
    1. 顺序,可以改
    2. 名字,不能改
  2. axios找不到
    1. 我用的是本地
    2. 大伙本地如果没有,用在线的
  3. 表单结构和我不同,获取的语法,不一样的

form表单-form-serialize插件

传送门:form-serialize插件

作用:

  1. form-serialize的作用是简化获取表单数据

使用步骤:

  1. 导入form-serialize插件
  2. 调用serialize传入form表单和选项,即可获取
    1. 导入之后全局会增加serialize方法
  3. 注意: 表单输入元素需要有值,才可以正常获取
serialize(form表单,{hash:true}) // 对象格式
serialize(form表单,{hash:false})// key=value格式

测试:

  1. 基于上一节的代码调整
  2. 测试{hash:true}{hash:false}的区别
  3. 使用插件替换数据部分的取值逻辑

form表单-form-serialize插件

这一节咱们学习了一个插件form-serialize,根据传入选项的不同,获取到的数据格式也略有差异:

  1. hash属性和获取到数据格式的对应关系

    1. 对象格式{key:value,key2:value2}-->{hash:true}
    2. 字符串格式key=value&key2=value2-->不写
  2. form-serialize简化了什么操作?

    1. 表单取值

三、FormData

FormData-基本使用

FormData

传送门:上传头像接口

传送门:MDN-FormData

概念:

  1. FormData是浏览器提供的内置对象
  2. key/value的形式保存数据
  3. 能够结合ajax进行数据提交

常用语法:

  1. 通过new关键字实例化
  2. .append(key,value)添加数据
  3. .get(key)获取key对应的值
  4. 可以保存文件
// 实例化时传入Form表单 自动获取数据
const data = new FormData(form表单)
// 直接输出看不到数据
console.log(data)
// 通过get方法获取对应的值
console.log(data.get('username')) 
console.log(data.get('email'))
console.log(data.get('habbit'))

// 添加键值对
data.append('friend','jack')
console.log(data.get('friend')) // jack

FormData-基本使用

FormData的基本语法,它可以用来保存数据,也可以结合ajax进行数据提交(目前还没结合ajax)

  1. 使用FormData是否需要导入其他.js文件?

    1. 不需要,是内置对象
  2. FormData的实例化对象通过哪个方法添加数据?

    1. append(name,value)
  3. FormData的实例化对象如何获取添加的数据?

    1. .get(name)

FormData-type=file语法补充

浏览器中可以使用文本域让用户选择文件,如果要结合FormData使用需要补充一些语法,咱们一起来看看

传送门:MDN-input type=file

传送门:MDN-限制可接受的文件类型

语法:

  1. accept属性引导用户选择文件
    1. 多个用,分隔
    2. image/*,所有图片
    3. 只是给用户引导,引导,引导
  2. onchange会在选择的文件改变时触发
  3. files属性可以获取选择的文件
<body>
  <input type="file" name="avatar" accept="image/*"  placeholder="请选择头像">
  <script>
    document.querySelector('input').onchange = function(e){
      console.log('文件信息', e.target.files[0])
    }
  </script>
</body>

FormData-文本域语法补充

  1. accept属性是否可以限制用户选择的文件?

    1. 不能限制,只是推荐
  2. onchange会在什么时候触发?

    1. 内容改变-->选了一个不同的文件
  3. files属性是什么类型?

    1. 伪数组

      1. key是数字,0,1,2,...
      2. 有length属性
    2. document.querySelectorAll()--->伪数组

FormData-头像上传接口

结合刚刚学习的语法,咱们来调用一下头像上传接口

传送门:MDN-input type=file

传送门:头像上传接口

需求:

  1. 测试头像上传接口
  2. 获取上传之后的图片地址
  3. 设置给img标签

模板:

  1. 实例化FormData
  2. 通过append方法添加数据(文件)
  3. 结合axiosdata提交
  <h2>直接通过FormData</h2>
  <input type="file" accept="image/*" >
  <img src="" alt="" />
  <button>上传</button>

FormData-头像上传接口

结合头像接口+FormData实现了头像上传,重点是演示如何调用这个接口,有如下需要掌握的点:

  1. FormDataappend方法中的key根据什么来设置?

    1. 根据接口文档设置
  2. FormData结合axios提交,设置在哪个属性?

    1. data
    2. 请求体中的数据,都是通过data来提交

小节回顾

重点内容有哪些呢?

  1. Form表单

    1. 默认表单提交数据页面会刷新
    2. 现在基本不用
  2. Form表单+ajax

    1. form表单的onsubmit事件

    2. button type=submit按钮的点击事件

    3. 两者选择一个,阻止默认行为e.preventDefault()

    4. axios({
          url:"",
          method:"",
          data:{
              username:document.querySelector("元素").value,
              food:document.querySelector("元素").value
              //...
          }
      })
      
  3. form-serialize

    1. 快速的获取表单元素中输入元素的value值
    2. serialize(form表单)-->key=value&key2=value2的格式
    3. serialize(form表单,{hash:true})-->{key:value,key2:value2}
  4. FormData+input type=file+axios 头像上传

demo-头像上传

传送门:头像上传接口

需求:

  1. 正常上传,替换默认图片
  2. 错误上传,提示用户

分析:

  <div class="thumb-box">
    <!-- 头像 -->
    <img src="./images/cover.jpg" class="img-thumbnail thumb" alt="">
    <div class="mt-2">
      <input type="file" id="iptFile" accept="image/*" style="display: none;">
      <!-- 选择头像图片的按钮 -->
      <button class="btn btn-primary" id="btnChoose">选择 & 上传图片</button>
    </div>
  </div>
  1. 如何点击按钮弹出文件选择框?
    1. 点击按钮的时候
    2. 拿到文件选择标签,触发一下它的click
  2. 发请求
    1. 什么时候发?
      1. input标签的 change事件中
    2. 携带什么参数?
      1. new FormData-->append(从文档看,e.target.files[0])
  3. 接收响应
    1. 在哪接收响应?
      1. then
    2. 接收到响应之后的逻辑?
      1. 设置imgsrc属性

demo-头像上传

这一节咱们完整实现了头像上传功能,界面也更为精美,有哪一些需要掌握的点呢?

  1. 如何点击按钮弹出文件选择框?
    1. 文件选择框.click()
  2. axios结合哪个对象可以上传文件?
    1. FormData
  3. 上传成功之后如何让img标签显示上传的图片呢?
    1. src属性

四、Content-Type

不同的数据格式

不同接口对于提交数据格式的要求略有不同,咱们结合接口文档的要求,看看axios如何提交这三种格式的数据

传送门:content-type

传送门:form的enctype

概念:

  1. axios是一个网络请求库,内部有很多的逻辑
  2. 对于接口对于数据格式的要求,开发者只需要传递对应格式的数据即可
  3. 其余的事情axios会帮我们做

测试

  1. 基于模板进行测试
  2. 通过如下3个接口确认body的格式
  3. axios在请求体中传递的数据通过data属性设置
  4. network中确认提交数据的原始格式
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h2>form-data</h2>
    <input class="ipt" type="file" accept="image/*" />
    <h2>application/json</h2>
    <button class="json">测试登录接口</button>
    <h2>urlencoded</h2>
    <button class="urlencoded">测试urlencoded格式</button>
    <script src="./lib/axios.js"></script>
    <script>
      // 1.测试formData
      document.querySelector('.ipt').onchange = function (e) {
        // 调用头像上传接口 提交图片
        const data = new FormData()
        data.append('avatar', e.target.files[0])
        axios({
          url: 'http://ajax-api.itheima.net/api/file',
          method: 'post',
          data: data,
        }).then(res => {
          console.log('res:', res)
        })
      }
      // 2.测试application/json
      document.querySelector('.json').onclick = function () {
        axios
          .post('http://ajax-api.itheima.net/api/login', {
            username: 'admin',
            password: '123456',
          })
          .then(res => {
            console.log('res:', res)
          })
      }
      // 3.测试 application/x-www-form-urlencoded
      document.querySelector('.urlencoded').onclick = function () {
        axios({
          url: 'http://ajax-api.itheima.net/api/data',
          method: 'post',
          data: 'name=jack&age=18&friend=rose',
        }).then(res => {
          console.log('res:', res)
        })
      }
    </script>
  </body>
</html>

不同的数据格式

这一节咱们测试了对于body格式要求不同的接口如何传递数据,由于用的是axios,我们只需要更改数据的格式即可

  1. 本节演示的三种数据格式都是通过axios()方法中的哪个属性提交?

    1. data
  2. multipart/form-data :提交什么格式?

    1. new FormData()
  3. application/json:提交的数据格式?

    1. 写成对象-->axios会帮我们转为JSON
  4. application/x-www-form-urlencoded :提交的数据格式?

    1. key=value&key2=value2

content-type的作用

上一节对比了几种对提交格式要求不同的接口如何调用,咱们只需要更改提交的内容格式即可,axios还帮咱们改了content-type,通过修改这个的值,告诉服务器提交的数据是什么格式

传送门:content-type

传送门:form的enctype

概念:

  1. 在响应中Content-Type 告诉客户端实际返回的内容的内容类型(浏览器根据这个判断如何解析)
  2. 在请求中,Content-type客户端告诉服务器实际发送的数据类型

查看方式:

  1. f12打开开发者界面
  2. 切换到network
  3. 点击请求即可查看

请求中Content-type对比

属性值 应用场景
application/x-www-form-urlencoded 表单中不包含文件上传的场景,适用于普通数据的提交(现在很少用)
multipart/form-data 表单中包含上传文件的场景
application/json 上传json格式数据(文本类)
  • 注意:不同的数据对应不同的请求类型,axios 默认帮我们做了设置处理

content-type的作用

这一节咱们通过请求报文确认了不同body格式,axios帮我们做的特殊处理,改了content-type

  1. 请求头中的content-type的作用是?

    1. 告诉 服务器, 提交的内容 是什么格式
  2. 使用axios提交不同格式的数据时,content-type是否需要开发者设置?

    1. 不需要,自动的设置
  3. 我们需要注意什么?

    1. 文档中明确告诉我们提交的数据格式是什么之后
    2. 能够根据文档提交不同的数据格式即可

五、图书管理

图书管理-准备工作

今天的最后来完成图书管理这个综合案例,巩固今天所学的内容,来明确一下需求,和文件的结构是什么样?

需求:

  1. 渲染数据列表
  2. 新增
  3. 删除
  4. 编辑(修改)

文件结构:

图书管理-准备工作 重点内容

  1. 项目中用到的UI库是?

    1. bootstrap
  2. 项目中请求库是?

    1. axios
  3. 项目中通过什么库简化表单数据获取?

    1. form-serialize

axios-基地址

项目中的接口一般开头部分是一样的,可以通过axios的基地址来统一设置,咱们来看看如何设置,并测试具体的效果

传送门:全局默认配置

语法:

  1. 设置基地址之后
  2. 请求的地址变为:基地址+url地址
// 设置一个
axios.defaults.baseURL='基地址'

测试:

  1. 测试设置了基地址之后如何发请求

axios-基地址

这一节咱们演示了如何设置基地址,可以通过它简化编码

  1. 设置基地址之后,后续的请求地址只需要写什么?
    1. 后面不同的部分
  2. 基地址适用场景?
    1. 项目中用的多

图书管理-列表渲染

首先完成列表渲染功能

传送门:图书列表接口

需求:

  1. 打开页面时,获取列表数据并渲染到页面上

分析:

  1. 通过接口测试工具测试接口是否可用?

  2. 设置基地址

    1. axios.defaults.baseURL
  3. 请求

    1. window.onload
      1. axios
  4. 响应

    1. .then
      1. arr->htmlarr->html->innerHTML

图书管理-列表渲染

这一节完成了列表渲染,虽然渲染的结构和之前的列表略有不同,套路是类似的,重点在接收到响应的渲染逻辑

  1. 接收到响应之后的逻辑

bootstrap-modal

新增和编辑都用到了bootstrap的弹框,咱们来看看如何使用它

传送门:boostrap中文网

概念:

  1. bootstrap提供了modal组件,简化弹框使用

用法1-基于属性:

  1. 通过文档确认并测试

用法2-基于js

  1. 通过文档确认并测试
  // Modal 参数 弹框的dom对象
  const myModal = new bootstrap.Modal(document.querySelector('#box'))
  console.log('myModal:', myModal)
  // 弹出弹框
  myModal.show()
  // 等3秒关闭
  setTimeout(() => {
    myModal.hide()
  }, 3000)

模板:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入 bootstrap 样式表 -->
    <link rel="stylesheet" href="./css/bootstrap.min.css" />
  </head>

  <body>
    <button>测试bootstrap的弹框</button>

    <!-- bootstrap的js -->
    <script src="./lib/bootstrap.min.js"></script>
  </body>
</html>

bootstrap-modal

这一节演示了bootstrap中modal组件的使用,并且演示了两种用法

  1. 是否需要背下来具体的代码?
    1. 不需要,随用随查
  2. 属性控制的适用场景?
    1. 没有逻辑,就是希望 显示/隐藏的时候可以通过属性空
  3. js控制的适用场景?
    1. 有逻辑,不仅要显示/隐藏,还要执行其他的逻辑

图书管理-新增

接下来完成新增功能

传送门:新增图书接口

需求:

  1. 点击新增弹出新增框
  2. 输入内容并点击提交时新增内容
  3. 新增完毕之后更新页面清空表单

分析:

  1. 点击弹框

  2. 请求

    1. 什么时候发请求?

      1. 点击确认
        1. onclick
    2. 是否需要提交数据?

      1. 通过插件获取数据+提交
  3. 响应

    1. 在哪里获取响应?

      1. .then
    2. 如何判断成功失败?

    3. 成功之后:关闭弹框清空表单,更新页面

    // 通过表单元素的reset方法实现清空
    const addForm = document.querySelector('#addForm')
    addForm.reset()
    
  4. 获取列表数据的逻辑上一步已经完成,抽取一下?

代码解析

图书管理-新增

这一节咱们完成了图书的新增逻辑,因为涉及到表单提交,清空,所以逻辑较多,但是核心还是围绕着请求和响应,有几个需要注意的地方

  1. 新增成功之后为什么需要重新通过接口获取数据?
    1. 新增--->服务器的数据变了
    2. 本地-->并没有
    3. 重新调用接口--->问服务器要数据

图书管理-删除

完成删除功能

传送门:图书删除接口

需求:

  1. 点击删除(可以提示用户)
  2. 根据id删除图书(服务器)
  3. 删除成功更新页面

分析:

  1. 通过接口测试工具测试接口是否可用?

    1. 可以用
  2. 请求:

    1. 什么时候发请求?

      1. 点击删除

      2. 事件委托绑定

        1. 删除按钮是动态生成的

        2. 绑定给始终存在的祖先元素(tbody)

    2. 是否需要提交数据?

      1. 传递id

      2. 保存自定义属性

        1. 存:data-book="xx"

        2. 取:dataset.book

  3. 响应:

    1. 在哪里获取响应?

      1. then
    2. 如何判断成功失败?

      1. 请求成功/失败
    3. 成功之后:更新页面

      1. 调用方法

图书管理-删除

这一节咱们完成了删除,依旧是围绕着请求和响应来完成的,有这么几个需要注意的细节哦

  1. 动态创建的元素如何绑定事件?

    1. 事件委托-->绑给它的祖先
  2. data-xxxdataset的作用?

    1. 保存数据:data-id='123'
    2. 获取保存的数据:dataset.id
  3. 删除图书删除的是保存在哪里的图书数据?

    1. 服务器,删除之后要更新页面

图书管理-编辑状态

接下来完成进入编辑的逻辑

传送门:图书详情接口

需求:

  1. 点击编辑,获取对应图书详情
  2. 弹出编辑框,填充对应的图书数据(包括id)

分析:

  1. 请求:

    1. 什么时候发请求?

      1. 点击编辑
      2. 事件委托
    2. 是否需要携带数据?

  2. 响应:

    1. 如何弹出编辑框?

      1. const modal =new boostrap.Modal(弹框)
      2. modal.show() /modal.hide()
    2. 编辑框中要保存什么数据?

      1. 当前点击的数据

图书管理-编辑状态

这一节咱们完成了图书编辑前半部分的逻辑,进入编辑状态,依旧围绕着请求和响应来完成,需要注意的点和新增有点类似:

  1. 动态创建的dom元素的如何绑定事件?

    1. 事件委托
  2. 为什么需要通过接口来获取图书的详情?

    1. 有可能拿行内的数据和服务器的数据不一致
    2. 直接问服务器要 最准确

图书管理-保存修改

最后来完成保存修改功能

传送门:图书修改

需求:

  1. 点击确认按钮更新图书数据
  2. 更新完毕之后,关闭弹框,更新列表数据

分析:

  1. 请求:

    1. 什么时候发请求?

      1. 点击确认 onclick
    2. 是否需要携带数据?

      1. form-->插件来生成
    3. 如何快速的获取数据?

      1. 插件来生成
  2. 响应:

    1. 接收到响应之后:关闭弹框,更新列表

      1. hide(),getBooks()
    2. 是否需要清空弹框中的内容?

      1. 不需要

      2. 因为点击编辑内部一定是有数据的

图书管理-保存修改

最后咱们完成了图书管理-保存修改的逻辑,核心依旧是请求和响应,但是编辑不同于新增,需要明确编辑的元素,这里通过传递id来完成:

  1. 图书的id保存的位置为什么要隐藏起来?

    1. 不让用户修改
  2. 图书管理案例中的图书数据保存在哪里?

    1. 服务器-->更新数据
posted @ 2022-08-03 11:15  苏神苏神我的超人  阅读(143)  评论(0)    收藏  举报