AJAX day2–form 表单 & 文件上传

AJAX day2–form 表单 & 文件上传1、form表单 1.1 表单的三个组成部分 1.1.1 表单的三个组成部分 – 表单标签 HTML 的 就是表单标签,它是一个“容器”,用来将页面上指定的区域划定为表单区域。 1.1.2 表单的三个

1、form表单

1.1 表单的三个组成部分

网页中采集数据的表单由三个部分组成,分别是:表单标签、表单域、表单按钮。

1.1.1 表单的三个组成部分 – 表单标签

  • HTML 的 就是表单标签,它是一个“容器”,用来将页面上指定的区域划定为表单区域。 image.png

1.1.2 表单的三个组成部分 – 表单域

  • 表单域提供了采集用户信息的渠道,常见的表单域有:input、textarea、select等。 image.png

1.1.3 表单的三个组成部分 – 表单按钮

  • 当表单数据填写完毕后,用户点击表单按钮,会触发表单的提交操作,从而把采集到的数据提交给服务器。

image.png

1.2 form标签的属性

  • form 标签最重要的 3 个属性分别是 action、method 和 enctype。
属性 可选值 说明
action 接口的 url 地址 把表单采集到的数据,提交到哪个接口中
method GET 或 POST 数据的提交方式(默认值为 GET)
enctype application/x-www-form-urlencoded multipart/form-data text/plain(很少用) 数据的编码格式。具体指的是:把表单数据提交给服务器之前,如何对将要提交的数据进行编码 (默认值 application/x-www-form-urlencoded)

1.3 以 GET 方式提交表单数据

  • 在 form 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 GET:

image.png

注意:由于method属性的默认值就是GET,因此上述的method=”GET” 可以被省略!

1.4 以 POST 方式提交表单数据

  • 在 form 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 POST,并通过 enctype 属性指定数据的编码方式为 application/x-www-form-urlencoded

image.png

注意:由于 enctype 的默认值就是 application/x-www-form-urlencoded,因此上述的 enctype 可以被省略!

1.5 表单提交的问题

  • form 表单既负责采集数据,又负责把数据提交到服务器!表单的默认提交行为会导致页面的跳转。

解决方案:

  1. form 表单只负责采集数据;
  2. Ajax 负责将数据提交到服务器。(符合:职能单一的原则)

1.6 通过 Ajax 提交表单数据

  • 通过 Ajax 提交表单采集到的数据,可以防止表单默认提交行为导致的页面跳转问题,提高用户的体验。

      1. 监听表单的 submit 提交事件
      1. 阻止默认提交行为
      1. 基于 axios 发起请求
      1. 指定请求方式、请求地址
      1. 指定请求体数据
axios({
          url: 'http://www.itcbc.com:3006/api/addbook',
          method: 'post',
          data: {
            bookname: bookname.value,
            author: author.value,
            publisher: publisher.value
          }
        }).then(result => {
        })
})
复制代码

1.7 jQuery 的 serialize() 函数

  • jQuery 的 serialize() 函数能够一次性获取到表单中采集的数据

    • 1、作用:收集指定表单中有name属性的表单元素的value值

    • 2、生成的格式为:key=value&key=value…

    • 3、问题:

      • 3.1 jq的方法,需要引入外部资源
      • 3.2 jq元素获取文件数据
    • 4、细节:name属性的值 需要和后台接口的参数对应

    • 5、其他特点:

      • 5.1 该方法 能够 获取 隐藏域的值
      • 5.2 该方法不能得到禁用状态的值
      • 5.3 该方法不能得到文件域中的文件信息,所以不能完成文件上传
  • 语法格式如下:

$('表单元素的选择器').serialize();
复制代码
  • 示例代码如下:
$('form').on('submit', function (e) {
    e.preventDefault()
    axios({
        method: 'POST',
        url: 'http://www.itcbc.com:3006/api/form',
        data: $('form').serialize()
    }).then(result => {
        console.log(result.data)
    })
})

2、axios 请求方法的别名

在实际开发中,常用的 5 种请求方式分别是: GET、POST、PUT、PATCH、DELETE

  • 为了简化开发者的使用过程,axios 为所有支持的请求方法提供了别名:
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

image.png

2.1 axios.get() 的用法

  • 使用 axios.get() 可以方便快捷地发起 GET 请求:
<body>
    <input type="text">
    <button class="all">查询全部数据</button>
    <button class="search">查询指定名称的数据</button>
    <script> let all = document.querySelector('.all') let search = document.querySelector('.search') let input = document.querySelector('input') all.addEventListener('click',function(){ // 不带查询参数 axios.get(`http://www.itcbc.com:3006/api/getbooks`).then(res => { console.log(res); }) }) search.addEventListener('click',function(){ let v = input.value // 带查询参数 // 在url中拼接参数 /* axios .get(`http://www.itcbc.com:3006/api/getbooks?bookname=${v}`) .then(res => { console.log(res); }) */ // 通过params传递参数 axios .get('http://www.itcbc.com:3006/api/getbooks',{ params: { bookname: v } }) .then(res =>{ console.log(res) }) }) </script>
</body>

2.2 axios.post() 的用法

  • 使用 axios.post() 可以方便快捷地发起 POST 请求:
// 不带请求体
axios.post('http://www.itcbc.com:3006/api/post').then(result => {
    console.log(result);
})
// 带请求体
axios.post('http://www.itcbc.com:3006/api/post', {
    username: 'zhangsan',
    password: '123456'
}).then(result => {
    console.log(result);
}

3、axios 全局配置 & 拦截器

3.1 全局配置请求根路径

  • 3.1.1 在 url 地址中,协议://域名:端口 对应的部分叫做“请求根路径”。

  • 3.1.2 全局配置请求根路径的好处:

    • 提高项目的可维护性。全局配置根路径后,后续所有的请求都可以使用全局配置的根路径
  • 3.1.3 假设:端口号从 3009 变成了 3006

    • 没有全局配置根路径,则每个请求的URL中的端口号都需要被修改!
    • 有全局配置根路径,则只需要修改全局配置即可

3.2 全局配置请求根路径 – 语法格式

基于 axios 提供的固定配置,即可轻松配置请求的根路径。语法格式如下:axios.defaults.baseURL = ‘请求根路径’

image.png

3.3 什么是拦截器

  • 拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。
  • 好处:可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性。

image.png

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  img.style.display = 'block'
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  img.style.display = 'none'
  return response;
}, function (error) {
  // 对响应错误做点什么
  img.style.display = 'block'
  return Promise.reject(error);
});

4、FormData

4.1 FormData 介绍

  • 4.1.1 FormData 作用

    • 收集常规的表单元素的数据
    • 收集文件数据,只有formdata可以实现
  • 4.1.2 axios所支持的参数格式

    • key=value&key=value
    • {key:value,key1:value1}
    • formdata
  • 4.1.3 收集常规表单元素的数据

    • 要求表单元素一定要有name属性,name属性的值就是参数的键名

    • 收集 过程:

      • 获取表单dom对象
      • let formdata = new FormData(表单dom对象)
  • 4.1.4 重点说明

    • 理论上axios支持传递formdata
    • 但是后台往往不会以formdata参数格式进行常规的业务处理,后台只有在有文件数据参与的时候接收formdata数据
    • 结论:能不能传递formdata由后台接口的处理方式来决定

4.2 FormData的API方法

  • 在提交数据前,可以使用下列API方法对数据进行查看和修改
append('key', 'value'); -- 向对象中追加数据
set('key', 'value');    -- 修改对象中的数据
delete ('key');         -- 从对象中删除数据
get('key')              -- 获取指定key的一项数据
getAll('key')           -- 获取指定key的全部数据
forEach()               -- 遍历对象中的数据
复制代码

4.3 FormData和serialize的区别

  • 共同点:

    • 都需要设置表单各项的name属性。
    • 都能快速收集表单数据
    • 都能够获取到隐藏域(<input type="hidden" />)的值
    • 都不能获取禁用状态(disabled)的值
  • 不同点:

    • FormData属于原生的代码;serialiaze是jQuery封装的方法
    • FormData可以收集文件域(<input type="file"/>)的值,而serialize不能。如果有文件上传,则必须使用FormData。
    • 得到的结果的数据类型不一样(知道即可)

4.4 FormData 实现头像上传

  • 主要的实现步骤:

    • 使用文件选择器选择图片文件
    • 把用户选择的文件存入 FormData 对象
    • 使用 axios 把 FormData 发送给服务器
    • 模拟文件选择器的点击事件
<!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="./lib/bootstrap-v4.6.0.css" />
    <style> .thumb-box { text-align: center; margin-top: 50px; } .thumb { width: 250px; height: 250px; object-fit: cover; border-radius: 50%; } </style>
  </head>

  <body>
    <div class="thumb-box">
      <!-- 头像 -->
      <img src="./images/cover.jpg" class="img-thumbnail thumb" alt="" />
      <div class="mt-2">
        <!-- 文件选择框 -->
        <!-- accept 属性表示可选择的文件类型 -->
        <!-- image/* 表示只允许选择图片类型的文件 -->
        <form action="">
          <input name="avatar" type="file" id="iptFile" accept="image/*" />
        </form>
      </div>
    </div>
    <script src="./lib/jquery-v3.6.0.js"></script>
    <script src="./lib/axios.js"></script>
    <script src="../utils/test.js"></script>
    <script> let iptFile = document.querySelector('#iptFile') // 当用户选择完文件之后触发事件 iptFile.addEventListener('change',function(){ // 使用axios结合formdata实现文件上传 let form = document.querySelector('form') let formdata = new FormData(form) console.log(formdata.get('avatar')); axios({ method: 'post', url: '/api/formdata', data: formdata }).then(res => { console.log(res); }) }) </script>
  </body>
</html>

5、图片预览

5.1 本地预览

  • 图片并不是单独进行上传的,意思就是说用户选择图片之后,并没有进行图片的上传,这个时候的预览和服务器是没有任何关系
<!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="./lib/bootstrap-v4.6.0.css" />
    <style> .thumb-box { text-align: center; margin-top: 50px; } .thumb { width: 250px; height: 250px; object-fit: cover; border-radius: 50%; } </style>
  </head>

  <body>
    <div class="thumb-box">
      <!-- 头像 -->
      <img src="./images/cover.jpg" class="img-thumbnail thumb" alt="" />
      <div class="mt-2">
        <!-- 文件选择框 -->
        <!-- accept 属性表示可选择的文件类型 -->
        <!-- image/* 表示只允许选择图片类型的文件 -->
        <form action="">
          <!-- 真正的页面中,可能不止只有文件域,还有其它的表单元素 -->
          <input type="text" name="username" />
          <input type="text" name="password" />
          <input name="avatar" type="file" id="iptFile" accept="image/png,image/jpeg" />
        </form>
      </div>
    </div>
    <script src="./lib/axios.js"></script>
    <script src="../utils/test.js"></script>
    <script> let iptFile = document.querySelector('#iptFile') let form = document.querySelector('form') let thumb = document.querySelector('.thumb') // 当用户选择完文件之后触发事件 iptFile.addEventListener('change',function(){ // 使用axios结合formdata实现文件上传 let formdata = new FormData(form) // 实现本地预览:加载本地图片的数据进行渲染 // 1.获取用户所选择的文件对象 // files:当前用户所选择的文件列表 let myfile = iptFile.files[0] // 2.根据用户选择的文件对象生成一个路径并返回 let myurl = URL.createObjectURL(myfile) // 3.将地址赋值给img标签的src属性 thumb.src = myurl console.log(formdata); console.log(formdata.get('avatar')); axios({ method: 'post', url: '/api/formdata', data: formdata }).then(res => { console.log(res); // 直接通过返回的formdata对象中的filename属性值赋值给img标签的src属性,实现头像的上传 // 缺点:需要等待响应时间 // thumb.src = res.data.data.filename }) }) </script>
  </body>
</html>

6、文件上传

  • 只要提交的数据中有文件,则必须使用formdata收集数据进行传递

  • 将所有数据(包含文件)统一上传

    let form = document.querySelector('form')
    let formdata = new FormData(form)
    复制代码
    
    • 实现图片的本地预览

      • 获取用户所选择的文件对象
      file表单元素.files[0]
      复制代码
      
      • 根据文件对象生成一个托管路径
      let url = URL.createObjectUrl(file对象)
      复制代码
      
      • 将路径赋值给img的src属性
      img.src = url
      复制代码
      
      • 为什么要这么做???

        • 1、没有上传给服务器,所以也没有服务器返回路径
        • 2、我们也拿不到当前用户所选择的文件路径
        • 3、所以我们只能根据文件对象生成一个路径,并赋值给img的src属性
<script> let iptFile = document.querySelector('#iptFile') let thumb = document.querySelector('.thumb') // 当用户选择完文件之后触发事件 iptFile.addEventListener('change', function() { // 使用axios结合formdata实现文件上传 let form = document.querySelector('form') let formdata = new FormData(form) // 实现本地预览:加载本地图片的数据进行渲染 // 1.获取用户所选择的文件对象 // files:当前用户所选择的文件列表 let myfile = iptFile.files[0] // 2.根据用户所选择的文件对象生成一个路径并返回 let myurl = URL.createObjectURL(myfile) // 3.将地址赋值给img标签的src属性 thumb.src = myurl }) </script>
复制代码
  • 只上传文件数据

    • 基本步骤

      • 1、获取文件对象

      • 2、创建formdata

      • 3、将文件对象做为参数追加到formdata中

        • formdata.append(‘后台接口规定的key’,用户所选择文件对象)
      • 4、将formdata做为参数传递给后台服务器

    • 预览

      • 将后台的返回路径赋值给img的src属性
<script> let iptFile = document.querySelector('#iptFile') // 当用户选择完文件之后触发事件 iptFile.addEventListener('change', function() { // 使用axios结合formdata实现文件上传 let formdata = new FormData() // 追加文件参数,可以追加任意的参数 formdata.append('avatar', iptFile.files[0]) axios({ url: '/api/formdata', method: 'post', data: formdata }).then(res => { console.log(res) }) }) </script>

7.请求报文 & 响应报文

  • 客户端与服务器通信的过程是基于请求与响应的。其中:
    • 请求报文规定了客户端以什么格式把数据发送给服务器
    • 响应报文规定了服务器以什么格式把数据响应给客户端

7.1 请求报文 – 格式

请求报文由请求行(request line)、请求头部( header )、空行 和 请求体 4 个部分组成。图示如下:

image.png

注意:

在浏览器中,GET 请求比较特殊,它只有请求头,没有请求体。

在浏览器中,POST、PUT、PATCH、DELETE 请求既有请求头,又有请求体。

7.2 响应报文 – 格式

响应报文由状态行、响应头部、空行 和 响应体 4 个部分组成。图示如下:

image.png

7.3 URL参数

  • 常用的5种请求方式,都可以在URL后面携带请求参数。
  • 由于URL的长度有限制,所以请求参数一般都比较小,比如不能做文件上传
  • 常用的请求参数有两种写法
    • /api/xxx?参数=值&参数=值 (这种格式的字符串叫做查询字符串,所以这样的参数叫做查询参数)
    • /api/xxx/值/值 (Restful 风格的接口用这种格式的参数)

axios中 如何携带不同格式的请求参数 具体用哪种格式得看接口文档

第一种格式的参数:(/api/xxx?参数=值&参数=值)

image.png

第二种格式的参数:( /api/xxx/值/值)

image.png

7.4 请求体

  • 除GET请求以外,其他4种常用的请求方式,都可以设置请求体。
  • 请求体的大小没有限制,所以可以提交大量的数据
  • 常用的请求体格式有如下三种:
    • 参数=值&参数=值 (查询字符串格式)
    • ‘{ “id”: 1, “name”: “zs” }’ (JSON格式)
    • new FormData() (FormData对象格式)

axios中,如何设置不同格式的请求体

  • 第一种格式:参数=值&参数=值

image.png

  • 第二种格式: ‘{ “id”: 1, “name”: “zs” }’

image.png

  • 第三种格式: new FormData()

image.png

请求的时候,设置了不同格式的请求体,需要一个对应的请求头

  • 第一种格式:参数=值&参数=值
    • Content-Type: application/x-www-form-urlencoded
  • 第二种格式: ‘{ “id”: 1, “name”: “zs” }’
    • Content-Type: application/json
  • 第三种格式: new FormData()
    • Content-Type: multipart/form-data; xxsd随机字符

7.5 http 响应状态码

概念:http 响应状态码(Status Code)由三位数字组成,用来标识响应成功与否的状态。

作用:客户端浏览器根据响应状态码,即可判断出这次 http 请求是成功还是失败了。

image.png

7.6 常见的 http 响应状态码

状态码 状态码描述 说明
200 OK 请求成功。
201 Created 资源在服务器端已成功创建。
304 Not Modified 资源在客户端被缓存,响应体中不包含任何资源内容!
400 Bad Request 客户端的请求方式、或请求参数有误导致的请求失败!
401 Unauthorized 客户端的用户身份认证未通过,导致的此次请求失败!
404 Not Found 客户端请求的资源地址错误,导致服务器无法找到资源!
500 Internal Server Error 服务器内部错误,导致的本次请求失败!

7.7 http 响应状态码 Vs 业务状态码

正确区分响应状态码和业务状态码的不同,是保证使用 Ajax 不迷茫的必要前提。从如下 3 个方面进行区分:1.所处的位置 2.表示的结果 3.通用性

1.所处的位置不同:

  • 在响应头的状态行中所包含的状态码,或者请求列表中的Status,叫做“响应状态码”

image.png

  • 在响应体的数据中所包含的状态码(案例中叫做code),叫做“业务状态码”

image.png

表示的结果不同:

  • 响应状态码只能表示这次请求的成功与否(成功地失败了)
  • 业务状态码用来表示这次业务处理的成功与否

通用性不同:

  • 响应状态码是由 http 协议规定的,具有通用性。每个不同的状态码都有其标准的含义,不能乱用。
  • 业务状态码是后端程序员自定义的,不具有通用性。

image.png

今天的文章AJAX day2–form 表单 & 文件上传分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/20317.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注