1、form表单
1.1 表单的三个组成部分
网页中采集数据的表单由三个部分组成,分别是:表单标签、表单域、表单按钮。
1.1.1 表单的三个组成部分 – 表单标签
- HTML 的 就是表单标签,它是一个“容器”,用来将页面上指定的区域划定为表单区域。
1.1.2 表单的三个组成部分 – 表单域
- 表单域提供了采集用户信息的渠道,常见的表单域有:input、textarea、select等。
1.1.3 表单的三个组成部分 – 表单按钮
- 当表单数据填写完毕后,用户点击表单按钮,会触发表单的提交操作,从而把采集到的数据提交给服务器。
1.2 form标签的属性
- form 标签最重要的 3 个属性分别是 action、method 和 enctype。
属性 | 可选值 | 说明 |
---|---|---|
action | 接口的 url 地址 | 把表单采集到的数据,提交到哪个接口中 |
method | GET 或 POST | 数据的提交方式(默认值为 GET) |
enctype | application/x-www-form-urlencoded multipart/form-data |
数据的编码格式。具体指的是:把表单数据提交给服务器之前,如何对将要提交的数据进行编码 (默认值 application/x-www-form-urlencoded) |
1.3 以 GET 方式提交表单数据
- 在 form 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 GET:
注意:由于method属性的默认值就是GET,因此上述的method=”GET” 可以被省略!
1.4 以 POST 方式提交表单数据
- 在 form 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 POST,并通过 enctype 属性指定数据的编码方式为 application/x-www-form-urlencoded
注意:由于 enctype 的默认值就是 application/x-www-form-urlencoded,因此上述的 enctype 可以被省略!
1.5 表单提交的问题
- form 表单既负责采集数据,又负责把数据提交到服务器!表单的默认提交行为会导致页面的跳转。
解决方案:
- form 表单只负责采集数据;
- Ajax 负责将数据提交到服务器。(符合:职能单一的原则)
1.6 通过 Ajax 提交表单数据
-
通过 Ajax 提交表单采集到的数据,可以防止表单默认提交行为导致的页面跳转问题,提高用户的体验。
-
- 监听表单的 submit 提交事件
-
- 阻止默认提交行为
-
- 基于 axios 发起请求
-
- 指定请求方式、请求地址
-
- 指定请求体数据
-
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]])
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 = ‘请求根路径’
3.3 什么是拦截器
- 拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。
- 好处:可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性。
// 添加请求拦截器
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 个部分组成。图示如下:
注意:
在浏览器中,GET 请求比较特殊,它只有请求头,没有请求体。
在浏览器中,POST、PUT、PATCH、DELETE 请求既有请求头,又有请求体。
7.2 响应报文 – 格式
响应报文由状态行、响应头部、空行 和 响应体 4 个部分组成。图示如下:
7.3 URL参数
- 常用的5种请求方式,都可以在URL后面携带请求参数。
- 由于URL的长度有限制,所以请求参数一般都比较小,比如不能做文件上传
- 常用的请求参数有两种写法
- /api/xxx?参数=值&参数=值 (这种格式的字符串叫做查询字符串,所以这样的参数叫做查询参数)
- /api/xxx/值/值 (Restful 风格的接口用这种格式的参数)
axios中 如何携带不同格式的请求参数 具体用哪种格式得看接口文档
第一种格式的参数:(/api/xxx?参数=值&参数=值)
第二种格式的参数:( /api/xxx/值/值)
7.4 请求体
- 除GET请求以外,其他4种常用的请求方式,都可以设置请求体。
- 请求体的大小没有限制,所以可以提交大量的数据
- 常用的请求体格式有如下三种:
- 参数=值&参数=值 (查询字符串格式)
- ‘{ “id”: 1, “name”: “zs” }’ (JSON格式)
- new FormData() (FormData对象格式)
axios中,如何设置不同格式的请求体
- 第一种格式:参数=值&参数=值
- 第二种格式: ‘{ “id”: 1, “name”: “zs” }’
- 第三种格式: new FormData()
请求的时候,设置了不同格式的请求体,需要一个对应的请求头
- 第一种格式:参数=值&参数=值
- 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 请求是成功还是失败了。
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,叫做“响应状态码”
- 在响应体的数据中所包含的状态码(案例中叫做code),叫做“业务状态码”
表示的结果不同:
- 响应状态码只能表示这次请求的成功与否(成功地失败了)
- 业务状态码用来表示这次业务处理的成功与否
通用性不同:
- 响应状态码是由 http 协议规定的,具有通用性。每个不同的状态码都有其标准的含义,不能乱用。
- 业务状态码是后端程序员自定义的,不具有通用性。
今天的文章AJAX day2–form 表单 & 文件上传分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/20317.html