AJAX
一、同步、异步
1、同步
代码按照顺序执行、立马获得结果就是同步,大多数代码都是同步的
2、异步
代码不一定按照顺序执行,执行后可能需要等待才会返回结果,比如定时器、promise等
二、服务器
服务器的本质:也是一台电脑。 服务器的作用: 存储一个网站的文件(HTML、CSS、JS、图片、音乐.....) 提供网站的文件给用户
资源
服务器上的 网页(html文件)、图片、音乐、视频、字体文件、CSS文件、JS文件等等都称之为资源。所以资源代指服务器上存储的内容。 通俗的讲,我们浏览网页时,从网络当中看到的内容都叫做资源。
三、客户端
概念:在前端开发中,客户端特指“Web 浏览器”。 作用:将互联网世界中的 Web 资源加载、并呈现到浏览器窗口中供用户使用。
URL地址(统一资源定位符)
URL 地址,表示服务器上每个资源的确切位置。
客户端与服务器通信的过程
客户端与服务器之间的通信过程,分为请求 - 响应两个步骤。 请求的概念:客户端通过网络去找服务器要资源的过程,叫做“请求” 响应的概念:服务器把资源通过网络发送给客户端的过程,叫做“响应”
四、什么是AJAX
Ajax 是浏览器中的技术:用来实现客户端网页请求服务器的数据。 它的英文全称是 Asynchronous Javascript And XML,简称 Ajax。
使用 Ajax 请求数据的 5 种方式
序号 | 请求方式 | 描述 |
---|---|---|
1 | POST | 向服务器新增数据 |
2 | GET | 从服务器获取数据 |
3 | DELETE | 删除服务器上的数据 |
4 | PUT | 更新服务器上的数据(侧重于完整更新:例如更新用户的完整信息) |
5 | PATCH | 更新服务器上的数据(侧重于部分更新:例如只更新用户的手机号) |
五、利用axios库发请求
操作服务器上的数据除了要使用 URL地址,还需要指定 请求方式
操作服务器上的数据时: 获取服务器上的数据,需要使用 get 方式 新增(添加)数据,需要使用 post 方式 删除数据,需要使用 delete 方式 完整修改(更新)数据,需要使用 put 方式 修改(更新)部分数据,需要使用 patch 方式
语法:
axios({
method: '请求的类型',
url: '请求的URL地址',
// 查询携带参数
// 也可以写在url后面
// http://api/getbooks?参数1=值&参数2=值
params:{
}
}).then((result) => {
// then 用来指定请求成功之后的回调函数
// 形参中的 result 是请求成功之后的结果
})
简写
axios.get() 直接发送get请求
axios.post() 直接发送post请求
axios.delete() 直接发送delete请求
axios.put() 直接发送put请求
axios.patch() 直接发送patch请求
1、get
axios.get('接口地址', {
params: {
appkey: 'hwx123'
}
}).then(result => {
console.log(result);
})
2、post
axios.post('接口地址', {
bookname: 'post请求1',
author: 'post请求222',
publisher: 'post请求33',
appkey: 'hwx123',
}).then(result => {
console.log(result);
})
// 2、
axios.post('接口地址','bookname=111222&author=222222&publisher=33333&appkey=hwx123').then(result => {
console.log(result);
})
六、利用axios库增加数据
语法:
axios({
method: 'POST',
url: '接口地址',
// 请求体
data: {
bookname: '水浒传',
author: '施耐庵',
publisher: '顺义出版社'
}
}).then(result => {
console.log(result)
})
post请求传参格式
axios({
method: 'post',
url: '接口地址',
data:'bookname=从入门到精通&author=我自己&publisher=出版社&appkey=hwx123'
/* data: {
bookname: '从入门到精通',
author: '我自己',
publisher: '出版社',
appkey: 'wanshao1234',
}, */
}).then((result) => {
console.log(result);
});
七、利用axios库编辑数据
在按钮设置自定义属性,根据自定义属性的值来编辑
语法:
<script>
// 根据数组下标修改
const tbody = document.querySelector('tbody')
const booknameValue = document.querySelector('.bookname')
const authorValue = document.querySelector('.author')
const publisherValue = document.querySelector('.publisher')
let arr = []
let id // 数组索引
const btn = document.querySelector('button')
tbody.addEventListener('click', function (event) {
if (event.target.nodeName === 'A') {
id = event.target.dataset.index
getIdData(id)
function getIdData(id) {
let IDdata
const url = '接口地址?id=' + id
axios.get(url).then(result => {
arr = result.data.data
updataList(arr)
})
}
// 数据展现在修改列表
function updataList(arr) {
booknameValue.value = arr[0].bookname
authorValue.value = arr[0].author
publisherValue.value = arr[0].publisher
}
}
})
btn.addEventListener('click', function () {
const url = 'http://www.itcbc.com:3006/api/updatebook'
const data = {
id:arr[0].id,
bookname: booknameValue.value,
author: authorValue.value,
publisher: publisherValue.value
}
axios.put(url,data).then(result => {
console.log(result);
getData()
})
})
getData()
function getData() {
const url = '接口地址'
const params = {
appkey: 'hwx123',
}
// 获取数据
axios.get(url, params).then(result => {
arr = result.data.data
render(arr)
})
}
function render(arr) {
let html = arr.map((value, index) => {
return `
<tr>
<td>${value.id}</td>
<td>${value.bookname}</td>
<td>${value.author}</td>
<td>${value.publisher}</td>
<td><a href='#' data-index='${value.id}'>编辑</a></td>
</tr>
`
}).join('')
tbody.innerHTML = html
}
</script>
八、利用axios库删除数据
把数据id设置在删除按钮上,根据id删除
<script>
const tbody = document.querySelector('tbody')
// 输入框的值
const bookname = document.querySelector('.bookname')
const author = document.querySelector('.author')
const publisher = document.querySelector('.publisher')
// 按钮
const btn = document.querySelector('button')
getData()
// 点击新增
btn.addEventListener('click', function () {
const title = bookname.value
const writer = author.value
const press = publisher.value
const data = {
bookname: title,
author: writer,
publisher: press
}
axios({
method: 'post',
url: '接口地址',
data,
}).then(result => {
getData()
bookname.value = ''
author.value = ''
publisher.value = ''
})
})
// 父元素绑定点击事件,利用事件委托
tbody.addEventListener('click', function (event) {
console.log(event.target.dataset.index);
if (event.target.nodeName === 'A') {
axios({
method: 'delete',
url: '接口地址',
params:{
id:event.target.dataset.index
}
}).then(result => {
getData()
})
}
})
// 获取数据
function getData() {
axios({
method: 'get',
url: '接口地址'
}).then(result => {
const arr = result.data.data
render(arr)
})
}
// 渲染函数
function render(arr) {
let html = arr.map(value => {
return `
<tr>
<td>${value.id}</td>
<td>${value.bookname}</td>
<td>${value.author}</td>
<td>${value.publisher}</td>
<td><a data-index='${value.id}' class='del' href="#">删除</a></td>
</tr>`
}).join('')
tbody.innerHTML = html
}
</script>
九、序列化
把对象或者数组 转成 字符串格式 过程 序列化 JSON.stringify();
把字符串格式 转成 对象或者数组 反序列化 JSON.parse()
1、利用jQuery快速获取表单数据序列化
const data = $('form表单选择器').serialize()
2、自定义快速获取表单数据
获取form表单里,带有name属性的值
const formObj = new FormData(document.querySelector('form'))
处理成 url 上的参数
const usp = new URLSearchParams(data)
const data = {
bookname: '书名',
author: '作者',
publisher: '出版社',
appkey: 'hwx123',
}
const usp = new URLSearchParams(data)
const str = usp.toString()
// bookname=书名&author=作者&publisher=出版社&appkey=hwx123
十、文件上传
1、input
type = file accept='images/*' 指定图片类型
2、this.files 数组
input.change事件,const file = this.files[0]获取当前文件
获取上传到浏览器的文件地址
const src = URL.createObjectURL(file) // 获取上传到浏览器内存中的文件
3、创建一个formdata对象
const formdata = new FormData()
4、按接口要求添加数据至formdata
formdata.append('avatar',file)
多个数据也一并添加至formdata
5、post发送请求
axios.post('接口地址/api/formdata',formdata).then(result => {
console.log(result);
})
<!-- accept="images/*" 指定文件类型 -->
<input type="file" accept="images/*" multiple> <!-- 此时什么类型都可上传 -->
<img src="" alt="">
<script src="./lib/axios.js"></script>
<script>
const input =document.querySelector('input')
const img =document.querySelector('img')
input.addEventListener('change',function () {
const file = this.files[0] // 获取当前事件的文件,可以上传多个文件,数组
console.log(file);
const src = URL.createObjectURL(file) // 获取上传到浏览器内存中的文件
img.src = src
// 接口地址/api/formdata
// 上传文件,给后端的参数 肯定是 formdata 类型
const formdata = new FormData() // 创建一个空的formdata对象
// 接口要求 参数名 avatar 参数类名file
formdata.append('avatar',file) // 接口要求,把文件追加到formdata对象
axios.post('接口地址/api/formdata',formdata).then(result => {
console.log(result);
})
})
</script>
十一、拦截器
分为请求拦截器和响应拦截器
<img src="./images/1.gif" alt="">
<button>按钮</button>
<script src="./lib/axios.js"></script>
<script>
// 添加请求拦截器
axios.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
// console.log('发送前 拦截器 ');
document.querySelector('img').style.display = 'block'
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
axios.interceptors.response.use(
function (response) {
document.querySelector('img').style.display = 'none'
return response;
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
);
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
axios.get('http://www.itcbc.com:3006/api/getbooks').then(result => {
console.log(result);
})
})
</script>
十二、原生ajax
写法
const xhr = new XMLHttpRequest()
// 添加请求方式和请求链接a
xhr.open('get','接口地址/api/getbooks?appkey=hwx123')
// 发送请求
xhr.send()
// 添加 load 事件
xhr.addEventListener('load',function () {
// 返回的数据 xhr.response
console.log(this.response);
// 是JSON格式,转成对象
const data = JSON.parse(this.response)
console.log(data);
})
1、get-携带参数
只能拼接再url上
const xhr = new XMLHttpRequest()
xhr.open('get','接口地址/api/getbooks?appkey=hwx123&bookname=嘿嘿')
xhr.send()
xhr.addEventListener('load',function () {
console.log(this.response);
})
2、post-携带参数
string类型格式
const xhr = new XMLHttpRequest()
xhr.open('post', '接口地址/api/addbook')
const data = 'bookname=Mkr&author=HWX&publisher=出版社&appkey=hwx123
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
// 3、发送
xhr.send(data)
xhr.addEventListener('load', function () {
console.log(this.response);
})
对象类型格式
const xhr = new XMLHttpRequest()
xhr.open('post', '接口地址/api/addbook')
const data = {
bookname: 'MkrRR',
author: 'HWXXXX',
publisher: '出版社',
appkey: 'hwx123',
};
// 1、转成JSON格式
const str = JSON.stringify(data)
// 2、指定请求头类型
xhr.setRequestHeader('Content-type', 'application/json')
// 3、发送
xhr.send(str)
xhr.addEventListener('load', function () {
console.log(this.response);
})
formdata类型格式
const file = this.files[0] // 获取当前事件的文件,可以上传多个文件,数组
console.log(file);
const src = URL.createObjectURL(file) // 获取上传到浏览器内存中的文件
img.src = src
// http://www.itcbc.com:3006/api/formdata
// 上传文件,给后端的参数 肯定是 formdata 类型
const formdata = new FormData() // 创建一个空的formdata对象
// 接口要求 参数名 avatar 参数类名file
formdata.append('avatar', file) // 接口要求,把文件追加到formdata对象
const xhr = new XMLHttpRequest()
xhr.open('post','接口地址/api/formdata'),
xhr.send(formdata)
xhr.addEventListener('load',function () {
console.log(this.response);
})
})
十三、请求报文&响应报文
客户端与服务器通信的过程是基于请求与响应的。其中: 请求报文规定了客户端以什么格式把数据发送给服务器 响应报文规定了服务器以什么格式把数据响应给客户端
请求报文 - 格式
请求报文由请求行(request line)、请求头部( header )、空行 和 请求体 4 个部分组成
注意: 在浏览器中,GET 请求比较特殊,它只有请求头,没有请求体。 在浏览器中,POST、PUT、PATCH、DELETE 请求既有请求头,又有请求体
响应报文 - 格式
响应报文由状态行、响应头部、空行 和 响应体 4 个部分组成
URL参数
常用的5种请求方式,都可以在URL后面携带请求参数。 由于URL的长度有限制,所以请求参数一般都比较小,比如不能做文件上传 常用的请求参数有两种写法 /api/xxx?参数=值&参数=值 (这种格式的字符串叫做查询字符串,所以这样的参数叫做查询参数)
// 直接写成查询字符串,并拼接到url后面
axios.get('/api/xxx?key=value&key=value')
// 按照axios的语法写,axios会帮我们转成查询字符串
axios.get('api/xxx', { params: { key: value, key: value } })
/api/xxx /值/值 (Restful 风格的接口用这种格式的参数)
// 只能自己拼接
axios.get('/api/xxx/100/zhangsan')
请求体
除GET请求以外,其他4种常用的请求方式,都可以设置请求体。 请求体的大小没有限制,所以可以提交大量的数据 常用的请求体格式有如下三种: 1、参数=值&参数=值 (查询字符串格式)
// axios.post的第二个参数,直接用查询字符串
axios.post('/api/xxx', 'key=value&key=value')
2、'{ "id": 1, "name": "zs" }' (JSON格式)
// axios.post的第二个参数,使用对象。axios会将它转成JSON格式
axios.post('/api/xxx', { id: 1, name: 'zs' })
3、new FormData() (FormData对象格式)
let fd = new FormData();
// axios.post的第二个参数,直接使用 FormData 对象
axios.post('/api/formdata', fd)
请求的时候,设置了不同格式的请求体,需要一个对应的请求头
1、参数=值&参数=值
Content-Type: application/x-www-form-urlencoded
2、'{ "id": 1, "name": "zs" }'
Content-Type: application/json
3、new FormData()
浏览器自动生成
http响应状态码
概念:http 响应状态码(Status Code)由三位数字组成,用来标识响应成功与否的状态。 作用:客户端浏览器根据响应状态码,即可判断出这次 http 请求是成功还是失败了。
响应状态码 | 含义 |
---|---|
200 | 服务器成功返回请求数据 |
201 | 新建或修改数据成功 |
202 | 一个请求已经进入后台排队(异步任务) |
204 | 删除数据成功 |
304 | 资源在客户端被缓存,响应体中不包含任何资源内容! |
400 | 发出信息有误 |
401 | 用户没有权限(令牌、用户名、密码错误) |
403 | 用户得到授权,但是访问是被禁止的 |
404 | 访问资源不存在 |
406 | 请求格式不可得 |
410 | 请求资源被永久删除,且不会被看到 |
500 | 服务器发生错误 |
502 | 网关错误 |
503 | 服务不可用,服务器暂时过载或维护 |
504 | 网关超时 |
http响应状态码 vs 业务状态码
1. 所处的位置不同:
在响应头的状态行中所包含的状态码,或者请求列表中的Status,叫做“响应状态码”
在响应体的数据中所包含的状态码 (案例中叫做code) ,叫做“业务状态码”
2. 表示的结果不同:
响应状态码只能表示这次请求的成功与否(成功地失败了) 业务状态码用来表示这次业务处理的成功与否
3. 通用性不同:
响应状态码是由 http 协议规定的,具有通用性。每个不同的状态码都有其标准的含义,不能乱用。 业务状态码是后端程序员自定义的,不具有通用性。
十四、封装Ajax
1、什么是 XMLHttpRequest
是浏览器内置的一个构造函数
作用:基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。 axios 中的 axios.get()、axios.post()、axios() 方法,都是基于 XMLHttpRequest(简称:XHR) 封装出来的!
2、主要实现步骤
主要的 4 个实现步骤: 创建 xhr 对象 调用 xhr.open() 函数 调用 xhr.send() 函数 监听 load 事件
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://xxx.com/api/xx');
xhr.send();
xhr.addEventListener('load', function () {
console.log(this.response);
})
3、自己封装AJAX
function ajax({ url, type, data = '', success }) {
const xhr = new XMLHttpRequest();
type = type.toLowerCase() // 全部转成小写
if (type === 'get') {
(typeof data === 'object') && (data = new URLSearchParams(data).toString());
xhr.open(type, url + '?' + data)
xhr.send()
} else if (type === 'post') {
xhr.open(type, url)
// 如果是字符串类型
if (typeof data === 'string') {
// 设置对应数据格式请求头
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
xhr.send(data)
// 如果是对象
} else if (typeof data === 'object') {
if (data instanceof FormData) { // 如果是formdata
xhr.send(data)
} else { // 普通对象
xhr.setRequestHeader('Content-type', 'application/json')
const str = JSON.stringify(data)
xhr.send(str)
}
}
}
xhr.addEventListener('load', function () {
const str = JSON.parse(this.response)
success(str)
})
}
十五、JSON数据
JSON(全称:JavaScript Object Notation)是一种数据交换格式,它本质上是用字符串的方式来表示对象或数组类型的数据。
1、JSON数据格式
JSON 数据的格式有两种:
① 对象格式
对象格式的 JSON 数据,最外层使用 { } 进行包裹,内部的数据为 "key": "value" 的键值对结构。其中: key 必须使用英文的双引号进行包裹 value 的值只能是字符串、数字、布尔值、null、数组、对象类型(可选类型只有这 6 种)
② 数组格式
数组格式的 JSON 数据,最外层使用 [ ] 进行包裹,内部的每一项数据之间使用英文的 , 分隔。其中: 每一项的值类型只能是字符串、数字、布尔值、null、数组、对象这 6 种类型之一。
2、JSON语法要求
- 使用 JSON 定义 JSON 格式的数据时,要遵守以下的 6 条规则:
- 属性名必须使用双引号包裹
- 字符串类型的值必须使用双引号包裹
- JSON 中不允许使用单引号表示字符串
- JSON 中不能写注释
- JSON 的最外层必须是对象或数组格式(其他类型也可以,但多数是对象或数组格式)
- 不能使用 undefined 或函数作为 JSON 的值
3、JSON数据和JS数据相互转换
JSON转JS
JSON.parse(data)
JS转JSON
JSON.stringify(data)
\