Ajax form 表单 & 文件上传

974 阅读3分钟

form 表单

负责数据采集功能

三个组成部分

  • 表单标签

    • HTML 的 就是表单标签,它是一个“容器”,用来将页面上指定的区域划定为表单区域
    • 最重要的 3 个属性

image.png

  • 表单域

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

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

jQuery 的 serialize() 函数

  • jQuery 的 serialize() 函数能够一次性获取到表单中采集的数据
  • $('表单元素的选择器').serialize()
  • 在使用 serialize() 函数快速获取表单数据时,必须为每个表单域添加 name 属性
  • 使用该方法得到的结果是一个查询字符串结构:name=value&name=value
  • 该方法 能够 获取 隐藏域的值
  • 该方法不能得到禁用状态的值
  • 该方法不能得到文件域中的文件信息,所以不能完成文件上传

axios 请求方法的别名

  • axios.get(url[, config])

  • axios.delete(url[, config])

  • axios.post(url[, data[, config]])

  • axios.put(url[, data[, config]])

  • axios.patch(url[, data[, config]])

  • 体验 axios.get() 的用法

 axios
          .get('http://www.itcbc.com:3006/api/getbooks', {
            // params:键只能写params
            params: { id: 11778 }
          })
          .then(result => {
            console.log(result)
          })

axios 全局配置 & 拦截器

全局配置请求根路径

  • axios.defaults.baseURL = '请求根路径'
// 配置基准路径(基地址),后期后自动的拼接在url前面,除非url是一个绝对路径
axios.defaults.baseURL = 'http://www.itcbc.com:3006'

拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应

  • 可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性

  • 使用拦截器 - 实现 loading 效果

/ 添加响应拦截器
// response:响应,所以响应都会经过这个拦截器
axios.interceptors.response.use(
  // 响应成功所经过的处理函数
  function(response) {
    // 对响应数据做点什么
    document.querySelector('.loading').style.display = 'none'
    return response
  },
  // 响应失败所经过的处理函数
  function(error) {
    // 对响应错误做点什么
    document.querySelector('.loading').style.display = 'none'
    return Promise.reject(error)
  }

FormData和文件上传

  • FormData 是一个浏览器对象。用于管理表单数据。

  • IE10+支持。

  • 可以这样理解,FormData的作用和 jQuery中的 serialize() 作用一样,用于快速收集表单数据

并且可以将创建的FormData对象直接提交给接口。

  • 典型应用场景:FormData + Ajax 技术实现文件上传的功能

  • 基本使用方法

// 1. 获取 form 标签的 DOM对象
let form = document.querySelector('form');
// 2. 实例化 FormData 对象,传入 form
let fd = new FormData(form);
// 3. 提交数据
axios.post('/api/formdata', fd).then(result => {
    console.log(result);
})

  • 要求,每个表单元素都具有 name 属性

  • FormData的API方法

append('key', 'value'); -- 向对象中追加数据
set('key', 'value');    -- 修改对象中的数据
delete ('key');         -- 从对象中删除数据
get('key')              -- 获取指定key的一项数据
getAll('key')           -- 获取指定key的全部数据
forEach()               -- 遍历对象中的数据

  • 头像上传案例

      let iptFile = document.querySelector('#iptFile')
      // 用户选择文件之后所触发的事件:change
      iptFile.addEventListener('change', function() {
        // console.log(iptFile.value)  拿不到,拿到的只是一个假路径
        // console.log($('form').serialize())  也拿不到,只到空字符串值
        // 使用formdata获取用户所选择文件数据,且文件数据只能使用formdata
        let form = document.querySelector('form')
        let fd = new FormData(form)
        console.log(fd.get('avatar'))
      })

FormData和serialize的区别

  • 共同点:

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

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

文件域补充

文件域:input type="file"

  • accept 属性:控制能够选择的文件类型,比如 accept="image/png,image/jpeg"

  • multiple 属性:控制是否可以多选文件

文件对象

  • 文件对象不需要自己创建,可以通过文件域获取得到
  • 选择一个或多个文件
  • 根据文件域,找到它的 files 属性。files属性是一个伪数组,里面包含了一个或多个文件对象。
  • 取得文件对象
        // files:当前用户所有文件的文件列表(伪数组),里面的每一个值都是文件对象
        let myfile = iptFile.files[0]
  • 作用之一

    • 本地预览
      // createObjectURL:可以将你传入的文件对象数据存储到内存,并返回内存中的存储地址(路径)
        // let url = URL.createObjectURL(文件对象)
        let myurl = URL.createObjectURL(myfile)
        thumb.src = myurl
  • 作用之二

    • 追加到FormData,实现文件上传
  let fd = new FormData()
        // appent追加参数到formdata,值可以是任意类型
        fd.append('avatar', myfile)

请求报文&响应报文

请求报文

  • 请求报文规定了客户端以什么格式把数据发送给服务器

image.png

  • 在浏览器中,GET 请求比较特殊,它只有请求头,没有请求体
  • 在浏览器中,POST、PUT、PATCH、DELETE 请求既有请求头,又有请求体

响应报文

  • 响应报文规定了服务器以什么格式把数据响应给客户端

image.png

  • 常用的5种请求方式,都可以在URL后面携带请求参数。
  • 由于URL的长度有限制,所以请求参数一般都比较小,比如不能做文件上传

常用的请求体格式

  • /api/xxx?参数=值&参数=值 (这种格式的字符串叫做查询字符串,所以这样的参数叫做查询参数)

// axios.post的第二个参数,直接用查询字符串
axios.post('/api/xxx', 'key=value&key=value')
  • /api/xxx/值/值

// axios.post的第二个参数,使用对象。axios会将它转成JSON格式
axios.post('/api/xxx', { id: 1, name: 'zs' })

  • new FormData() (FormData对象格式
let fd = new FormData();
// axios.post的第二个参数,直接使用 FormData 对象
axios.post('/api/formdata', fd)