1.请求报文和响应报文
1.请求报文
2.响应报文
3.请求体
4.HTTP 响应码
2-3开头正常,4开头前端问题,5开头后端问题
5.HTTP 状态码
HTTP 状态码是公共的,业务状态码是公司自己定义的
查询地址:www.runoob.com/http/http-s…
XMLHttpRequest
2.Ajax-原生代码写法
就是不引入axios的原生写法,要自己加json转化对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>03-原生ajax.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
// 1 创建 xhr对象
const xhr = new XMLHttpRequest();
// 2 调用 open方法 指定 请求类型,url
xhr.open('get', 'http://www.itcbc.com:3006/api/getbooks');
// 3 发送出去 send 发送Ajax(网络请求)
xhr.send();
// 4 监听onload 数据响应事件
xhr.addEventListener('load', function () {
// this
console.log('数据回来啦');
// console.log(this.response);
// 字符串转对象
const obj = JSON.parse(this.response);
console.log(obj);
});
//axios封装的写法
// axios.get("http://www.itcbc.com:3006/api/getbooks")
// .then(result)
</script>
</body>
</html>
3.Ajax-get-原生代码携带参数写法
<!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>
<script>
const xml = new XMLHttpRequest()
//get原生代码携带参数写法
xml.open('get', 'http://www.itcbc.com:3006/api/getbooks?appkey=lishupeng123&bookname=聂成林')
xml.send()
xml.addEventListener('load', function () {
const obj = JSON.parse(this.response)
console.log(obj);
})
</script>
</body>
</html>
4.content-type
类型格式
5.原生-post-携带参数
设置对应的 content-type才能显示对应的浏览器格式 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.send(query); // 传递 a=b&c=d
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>05-原生-post-携带参数.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<!-- <form action="" enctype="application/x-www-form-urlencoded" ></form> -->
<script>
const xhr = new XMLHttpRequest();
// open 来指定 请求方式
xhr.open('post', 'http://www.itcbc.com:3006/api/addbook');
// bookname: '从入门到精通',
// author: '我自己',
// publisher: '黑马出版社',
// appkey : wanshao1234
// post请求的参数 只能卸载 send()
// post 三种不同数据格式的参数
// 1 a=b&c=d 同时也需要指定 content-type 才行!!
// 2 对象格式 {a:"b",c:"d"} 同时也需要指定 content-type 才行!!
// 3 formdata 数据
const data = {
bookname: '1从入门到精通1',
author: '我自己',
publisher: '黑马出版社',
appkey: 'wanshao1234',
};
// 把data 转成 a=b&c=d .... URLSearchParams
const usp=new URLSearchParams(data);
const query = usp.toString();
// 设置对应的 content-type
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(query); // 传递 a=b&c=d
xhr.addEventListener('load', function () {
console.log(this.response);
});
</script>
</body>
</html>
6-原生-post-携带参数-json
要设置相应的 // 设置对应的 content-type才能显示对应的浏览器格式 xhr.setRequestHeader("Content-type", "application/json"); const str = JSON.stringify(data);
xhr.send(str); // 传递 a=b&c=d
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>06-原生-post-携带参数-json</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<!-- <form action="" enctype="application/json" ></form> -->
<script>
const xhr = new XMLHttpRequest();
xhr.open('post', 'http://www.itcbc.com:3006/api/addbook');
// post 三种不同数据格式的参数
// 1 a=b&c=d 同时也需要指定 content-type 才行!!
// 2 对象格式 {a:"b",c:"d"} 同时也需要指定 content-type 才行!!
// 3 formdata 数据
const data = {
bookname: '2从入门到精通2',
author: '我自己',
publisher: '黑马出版社',
appkey: 'wanshao1234',
};
// 设置对应的 content-type
xhr.setRequestHeader("Content-type", "application/json");
const str = JSON.stringify(data);
xhr.send(str); // 传递 a=b&c=d
xhr.addEventListener('load', function () {
console.log(this.response);
});
</script>
</body>
</html>
7-原生-post-携带参数-formdata
原生-post的参数是写xhr.send(formdata);里面的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>07-原生-post-携带参数-formdata</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<input type="file" accept="image/*" />
<script>
const input = document.querySelector('input');
input.addEventListener('change', function () {
const file = this.files[0];
const formdata = new FormData();
formdata.append('avatar', file);
const xhr = new XMLHttpRequest();
xhr.open('post', 'http://www.itcbc.com:3006/api/formdata');
// 不用设置 content-type
xhr.send(formdata);
xhr.addEventListener('load', function () {
console.log(this.response);
});
});
</script>
</body>
</html>
8.ajax代码的封装
自己动手封装类似jq或者axios那种函数实现方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>08-ajax代码的封装.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
/*
1 ajax 是一个函数(正解) 还是 一个对象
2 它接受一个 参数 格式 什么格式(对象)
3 需要在ajax函数中 写完 整个原生ajax 发送请求的代码
*/
const option = {
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'get',
data: 'appkey=wanshao1234',
success(result) {
// result 等于 要等于响应的数据 = 对象格式
console.log(result);
},
};
// 里面方法 option.success(2);
ajax(option);
function ajax(config) {
const xhr = new XMLHttpRequest();
xhr.open(config.type, config.url + '?' + config.data);
xhr.send();
xhr.addEventListener('load', function () {
// 响应的数据 this.response
// console.log(this.response);
const obj = JSON.parse(this.response)
config.success(obj)
});
}
</script>
</body>
</html>
9.ajax代码的封装.-get-不携带参数-优雅
用到了形参默认值和解构,让代码看的更简单一点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>11-ajax代码的封装.-get-不携带参数-优雅.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
// 形参默认值
// 解构
// function func(msg="hello") {
// console.log(msg);
// }
// func();// undefined
// func();// 输出默认值
// func('你好'); /// 你好
// const option = {
// type: 'get',
// data: 'a=1',
// };
// const { data } = option;
// console.log(data); // a=1
// function func(config) {
// const {data}=config;
// console.log(data);
// }
// function func({ data = '1' ,type}) {
// // 解构 同时也设置了默认值
// // console.log(data);
// console.log(type);
// }
// func(option);
const option = {
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'get',
// data: 'appkey=wanshao1234',
success(result) {
console.log(result);
},
};
ajax(option);
ajax({
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'get',
data: 'appkey=wanshao1234',
success(result) {
console.log(result);
},
});
function ajax({ url, type, data = '', success }) {
// 封装的时候考虑到用户 (可能带参数 , 可能不带参数)
const xhr = new XMLHttpRequest();
xhr.open(type, url + '?' + data);
// 如果 data没有值 url = http://www.itcbc.com?
// 如果 data有值 url = http://www.itcbc.com?appkey=wanshao1234
xhr.send();
xhr.addEventListener('load', function () {
const obj = JSON.parse(this.response);
success(obj);
});
}
</script>
</body>
</html>
10.ajax代码的封装.-get-对象格式的参数
就是转化对象格式的要怎么转化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>12-ajax代码的封装.-get-对象格式的参数</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
// 1
ajax({
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'get',
// data: 'appkey=wanshao1234',
success(result) {
console.log(result);
},
});
// 2
ajax({
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'get',
data: 'appkey=wanshao1234',
success(result) {
console.log(result);
},
});
// 3
ajax({
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'get',
data: {
appkey: 'wanshao1234',
bookname: '今晚吃啥',
},
success(result) {
console.log(result);
},
});
function ajax({ url, type, data = '', success }) {
const xhr = new XMLHttpRequest();
if (typeof data === 'object') {
// data是一个对象
data = new URLSearchParams(data).toString();
}
// (typeof data === 'object')&&(data = new URLSearchParams(data).toString())
xhr.open(type, url + '?' + data); // a=1&b=2 URLSearchParams
xhr.send();
xhr.addEventListener('load', function () {
const obj = JSON.parse(this.response);
success(obj);
});
}
// typeof
// console.log(typeof "" === 'object'); // 数据是不是对象格式
</script>
</body>
</html>
11.ajax代码-post
判断请求参数是什么然后输出对应的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>13-ajax代码-post.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
ajax({
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'get',
success(result) {
console.log(result);
},
});
ajax({
url: 'http://www.itcbc.com:3006/api/getbooks',
type: 'post',
success(result) {
console.log(result);
},
});
function ajax({ url, type, data = '', success }) {
const xhr = new XMLHttpRequest();
// 判断 请求类型
if (type === 'get') {
// get请求的相关的代码
if (typeof data === 'object') {
data = new URLSearchParams(data).toString();
}
xhr.open(type, url + '?' + data);
xhr.send();
} else if (type === 'post') {
// post请求的相关的代码
xhr.open(type, url);
xhr.send();
}
xhr.addEventListener('load', function () {
const obj = JSON.parse(this.response);
success(obj);
});
}
</script>
</body>
</html>
12.ajax代码-post-data传参
判断此时的data是什么类型的,然后解析出对应的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>14-ajax代码-post-data传参</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<input type="file" accept="image/*" />
<script>
/*
判断当前data的数据类型
1 字符串类型
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(data); // 传递 a=b&c=d
2 对象类型
xhr.setRequestHeader("Content-type","application/json");
const str =JSON.stringify(data);
xhr.send(str); // 传递 a=b&c=d
3 formdata
xhr.send(formdata);
*/
// const data="a=1&c=1"
// const data={};
// FormData 构造函数 (爸爸)
// data 实例 (儿子)
// const arr = new Array();
// const data = new FormData();
// 判断当前数据 字符串类型 typeof
// console.log( typeof data === "string" ); // 字符串类型
// console.log( typeof data === "object" ); // 对象类型
// console.log(typeof data);
// 判断你儿子 是不是亲生
// 儿子 instanceof 爸爸
// 实例 instanceof 构造函数
// console.log( data instanceof FormData );
// console.log(data instanceof Array);
// ajax({
// url: 'http://www.itcbc.com:3006/api/addbook',
// type: 'post',
// data:"bookname=%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A111&author=%E6%88%91%E8%87%AA%E5%B7%B1&publisher=%E9%BB%91%E9%A9%AC%E5%87%BA%E7%89%88%E7%A4%BE&appkey=wanshao1234",
// success(result) {
// console.log(result);
// },
// });
// ajax({
// url: 'http://www.itcbc.com:3006/api/addbook',
// type: 'post',
// data: {
// bookname: '从入门到精通222',
// author: '我自己',
// publisher: '黑马出版社',
// appkey: 'wanshao1234',
// },
// success(result) {
// console.log(result);
// },
// });
const input = document.querySelector('input');
input.addEventListener('change', function () {
const file = this.files[0];
const formdata = new FormData();
formdata.append('avatar', file);
ajax({
url: 'http://www.itcbc.com:3006/api/formdata',
type: 'post',
data: formdata,
success(result) {
console.log(result);
},
});
});
function ajax({ url, type, data = '', success }) {
const xhr = new XMLHttpRequest();
// 判断 请求类型
if (type === 'get') {
// get请求的相关的代码
if (typeof data === 'object') {
data = new URLSearchParams(data).toString();
}
xhr.open(type, url + '?' + data);
xhr.send();
} else if (type === 'post') {
// 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') {
// 判断是不是对象
// 判断是不是 FormData 实例
if (data instanceof FormData) {
// 是 FormData 实例
xhr.send(data);
} else {
// 普通的对象
xhr.setRequestHeader('Content-type', 'application/json');
const str = JSON.stringify(data);
xhr.send(str); // 传递 a=b&c=d
}
}
}
xhr.addEventListener('load', function () {
const obj = JSON.parse(this.response);
success(obj);
});
}
</script>
</body>
</html>
13.防抖
就是输入框不会输一个字发送一次请求,原理就是设一个延时器和清除延时器实现对应的功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>15-防抖</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
table {
width: 1000px;
margin: 0 auto;
}
thead tr {
background-color: blue;
color: #fff;
font-size: 20px;
}
tbody tr:nth-child(odd) {
background-color: green;
color: #fff;
font-size: 18px;
}
tbody tr:nth-child(even) {
background-color: peru;
color: #fff;
font-size: 18px;
}
td,
th {
padding: 10px;
}
input {
width: 1000px;
display: block;
margin: 30px auto;
height: 100px;
border-radius: 50px;
border: none;
background-color: skyblue;
font-size: 40px;
text-indent: 20px;
color: #666;
outline: none;
}
</style>
</head>
<body>
<input type="text" />
<table>
<thead>
<tr>
<th>id</th>
<th>书名</th>
<th>作者</th>
<th>出版社</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script src="../lib/axios.js"></script>
<script>
/*
防抖 防止抖动
1 用在输入框中 实现 不用用户按下回车键 就发送请求
2 技术原理
1 用新的一次输入来清除上一次的延时器
2 同时开启一个新的延时器
*/
getData();
// change事件 输入框的值发生改变-输入框失去焦点 才触发
// input 事件
// 定义一个 演示器 id
// let timeid; // 钻 石 城 堡
const input = document.querySelector('input');
// input.addEventListener('input', function (event) {
// clearTimeout(timeid);
// // 开启了一个延时器 里面代码 1s后会执行
// timeid = setTimeout(function () {
// }, 1000);
// });
let time;
input.addEventListener('input', function (even) {
clearTimeout(time)
time = setTimeout(() => {
const value = input.value.trim();
const queryStr = `?bookname=${value}`;
getData(queryStr);
}, 1000);
})
function getData(query = '') {
axios({
method: 'get',
url: 'http://www.itcbc.com:3006/api/getbooks' + query,
// params:{},
}).then((result) => {
console.log(result);
const arr = result.data.data;
render(arr);
});
}
function render(arr) {
let html = arr
.map(
(value) => `
<tr>
<td>${value.id}</td>
<td>${value.bookname}</td>
<td>${value.author}</td>
<td>${value.publisher}</td>
</tr>
`
)
.join('');
document.querySelector('tbody').innerHTML = html;
}
</script>
</body>
</html>
14.节流
上一次的业务没有结束的话 不允许开启下一次业务,两种实现方法,一是经验按钮,二是起一个变量来判断
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title>16-节流.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<button>获取数据</button>
<script src="../lib/axios.js"></script>
<script>
/*
节流
上一次的业务没有结束的话 不允许开启下一次业务
使用场景 移动端分页 - 倒计时按钮 等等
*/
// 这一次请求还没有结束 就不能开启下一个请求
// 业务 分页 业务
// 开关
let isLoadding = false; // 有没有请求在发送当中
// 点击按钮的时候先判断 isLoadding true还是false
// true 请求在发送中 return
// false 没有请求
// 先设置 isLoadding true
// 发送请求出去
// 请求回来了 设置 isLoadding = false
document.querySelector('button').addEventListener('click', function () {
if (isLoadding) {
return;
}
isLoadding = true;
// 发送请求的时候 禁用按钮
// this.disabled=true;
getData();
});
function getData(query = '') {
console.log('请求发送出去');
axios({
method: 'get',
url: 'http://www.itcbc.com:3006/api/getbooks' + query,
// params:{},
}).then((result) => {
console.log('数据回来了');
// document.querySelector('button').disabled=false
isLoadding = false;
});
}
</script>
</body>
</html>