ajax第一天
1.接口
被请求的 URL 地址,就叫做接口或API 接口
每个接口必须有对应的请求方式
2.接口文档
接口的使用说明书
3.通过id获取元素
id名可以直接获取dom元素,无需通过document.querySelector()方式
<input id="book" type="text" placeholder="请输入书籍" />
<script>
console.log(book);//<input id="book" type="text" placeholder="请输入书籍">
</script>
4.axios
参数
需要去官网下载axios.js引入使用
第一种参数携带方式:写在url问好后面,用等号连接参数和值
GET DELETE可以用此方式
axios({
// 请求参数 英文的符号为分割
// ? 前面部分是正常的url
// ? 后面的参数部分 a=1&b=2
url: 'http://www.itcbc.com:3006/api/getbooks?bookname=斗破苍穹134&author=我自己',
method: 'GET',
}).then(result=>{
console.log(result);
})
第二种参数携带方式:写在params对象中
params
只是让我们可以传递对象格式的参数,axios底层还是会把它转成 url的方式拼接在url后
GET DELETE参数放在params
中
放在data
中的参数是不会转成url方式拼接在url后的
POST PUT PATCH参数放在data
中
axios({
url: 'http://www.itcbc.com:3006/api/getbooks',
method: 'GET',
params: {
bookname: '斗破苍穹134',
author: '土豆',
}
}).then((result) => {
console.log(result);
});
GET
可以不带参数,带参数可以在 url上传递,也可以通过 params
来传递
POST
在 axios
中,发送 post
请求时,需要在 data
中来传递参数
axios({
url:"http://www.itcbc.com:3006/api/addbook",
method:"POST",
data:{
bookname:"从入门到出去",
author:"黑马77",
publisher:"白马",
appkey:"sdfr34343"
}
}).then(result=>{
console.log(result);
})
DELETE
参数在 params
中或者 url
上来添加
PUT和PATCH
都是在 data
上 传递数据
ajax第二天
1.data参数传递方式
对象格式传递
data: {
bookname: '演示',
author: '我自己你不知道',
publisher: '斑马出版社',
appkey: 'bbccddaaa',
}
字符串格式传递
data: 'bookname=演示&author=我自己你不知道&publisher=斑马出版社&appkey=bbcc33aaa'
2.form表单和按钮组成的页面刷新问题
form表单和按钮一起出现有一个浏览器默认提交而导致整个网页刷新的问题
解决方式1:按钮添加type="button"属性
按钮默认type属性值为submit,修改为button后不会有刷新页面问题
<button type="submit">登录</button>
解决方式2:
阻止form的提交导致的默认刷新行为,此时button的type属性不能是button,提交数据后,form会触发一个submit事件,通过e.prevent()阻止默认刷新,这种方式也是更适合的方式
const form = document.querySelector('form');
form.addEventListener('submit', function (event) {
event.preventDefault(); // 阻止 默认行为
console.log('表单提交 但是不刷新');
});
3.jQuery快速获取表单的值
需要用form
包裹表单标签,且表单元素需要有name
属性
序列化
serialize
把数据转成字符串的做法
jq快速获取表单值的方法:序列化
使用步骤
引入jquery.js
<script src="./lib/jquery.js"></script>
第一种方式:固定代码$('form标签的选择器').serialize()
第二种方式:固定代码$(form的dom元素).serialize()
序列化后得到字符串格式参数
<script src="./lib/jquery.js"></script>
<script>
const form = document.querySelector('form');
form.addEventListener('submit', function (event) {
event.preventDefault();
const query = $('form').serialize();
console.log(query);//username1=..&username2=..&username3=..
});
</script>
4.FormData第一个作用--快速获取form中的表单
同样需要用form
包裹表单标签,且表单元素需要有name
属性
FormData
FormData
构造函数 通过new 得到实例对象
把form标签中的表单 获取到 存在 fd实例对象中
const fd = new FormData(form的dom元素)
new出来的实例对象不能像普通对象通过点语法添加属性属性值,必须通过append
方法添加属性属性值
new出来的实例也不能直接打印看数据,要通过forEach
方法遍历挨个查看数据
const fd = new FormData();
fd.append("username","悟空");// 添加数据
// fd.append("height","180");// 添加数据
// fd.append("文件名称",文件);// 添加数据
fd.forEach((value,key)=>{
console.log("你要查看的属性名是",key,"属性值是",value);
})
拿表单值案例
<form>
<input type="text" name="username" value="111" />
<input type="text" name="password" value="222" />
<button>获取数据</button>
</form>
<script>
const form = document.querySelector('form');
form.addEventListener('submit', function (event) {
event.preventDefault();
// const fd=new FormData(传入一个form的dom元素);
// const fd=new FormData(form);
const fd = new FormData(this);
const list = [];
fd.forEach((value, key) => {
list.push(`${key}=${value}`);
});
// console.log(list);
const query = list.join('&');
console.log(query);//username1=..&username2=..&username3=..
});
</script>
URLSearchParams
也是一个构造函数
实例化后的对象也不能直接打印输出
主要作用:把数据转成 字符串参数形式
const form = document.querySelector('form');
form.addEventListener('submit', function (event) {
event.preventDefault();
// 1 快速把form标签中的表单 获取到 存在 fd对象中
const fd = new FormData(this);
// 2 把fd中的表单数据 存在usp对象
const usp = new URLSearchParams(fd);
console.log(usp); //URLSearchParams {} 空对象
// 3 usp对象 有一个方法 专门把数据转成 字符串参数形式 toString()
const query = usp.toString();
console.log(query);//username1=..&username2=..&username3=..
});
封装为函数:
function toQuery(form) {
const fd = new FormData(form);
const usp = new URLSearchParams(fd);
const query = usp.toString();
return query;
}
5.axios的简写
get 和 delete
不带参数:
axios.get('http://www.itcbc.com:3006/api/getbooks').then((result) => {
console.log(result);
});
带参数:
axios.get('http://www.itcbc.com:3006/api/getbooks', {
params: { appkey: 'bbccddaaa' },
})
.then((result) => {
console.log(result);
});
post put patch
axios.post('http://www.itcbc.com:3006/api/addbook', {
bookname: '演示ttt',
author: '我自己你不知道ttt',
publisher: '斑马出版社ttt',
// 改为只有自己知道的key 长度 6-20
appkey: 'bbccddaaa',
})
.then((result) => {
console.log(result);
});
6.axios基地址
作用
1.方便后期由开发服务器转生产服务器而导致的切换地址
2.方便我们在开发时少些一些url
写法
1.axios.defaults.baseURL = '网址前缀'
2.axios.get('/api/getbooks')
// 定义 axios基地址
axios.defaults.baseURL = 'http://www.itcbc.com:3006';
axios.get('/api/getbooks', {
params: { appkey: 'bbccddaaa' },
})
.then((result) => {
console.log(result);
});
7.FormData第二个作用--上传文件到服务器
把图片显示到浏览器
给file类型的input标签绑定chang
事件
change
事件触发时期 : 文件加载到浏览器内存中时触发
获取文件数据: dom.files[0]
URL.createObjectURL(dom.files[0])
获取到该文件在浏览器内存中地址
把地址设置给图片标签的src属性
<input type="file" name="" id="" />
<img src="" alt="" />
<script>
const input = document.querySelector('input');
const img = document.querySelector('img');
// change事件 触发时期 : 文件加载到浏览器内存中 触发
input.addEventListener('change', function () {
// files属性查看文件
console.log(this.files);
// 获取到图片在内存中的地址
// URL.createObjectURL(你想要获取谁的内存地址) 返回 内存中的 文件地址
const url = URL.createObjectURL(this.files[0]);
// 把内存中的图片 的地址 设置给 真正的图片标签
img.src = url;
console.log(url);
});
</script>
FormData把文件发送给服务器
1.先new一个FormData
对象
2.使用FormData
的append(key,value)
来添加文件,key属性名看文档设置,value就是要上传的文件this.files[0]
3.按接口文档要求请求上传
4.请求的文件---FormData
的实例对象fd
<input type="file" name="" id="" />
<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 url = URL.createObjectURL(this.files[0]);
img.src = url;
// 使用formData来包装数据
const fd = new FormData();
// 添加数据
// fd.append("avatar",文件)
fd.append('avatar', this.files[0]);
// 请求三大关键
// url method data
// axios.post("http://www.itcbc.com:3006/api/formdata",{a:1,b:2})
axios
.post('http://www.itcbc.com:3006/api/formdata', fd)
.then((result) => {
console.log(result);
});
});
</script>
ajax第三天
1.请求报文
请求行
请求头
空行
请求体--携带参数
GET
请求只有请求头 没有请求体 因为GET
请求参数需以键值对形式拼接在url?之后
POST、PUT、PATCH、DELETE 请求既有请求头,又有请求体
2.响应报文
状态行
响应头
空行
响应体--返回的数据
3.http响应状态码
1xx 不用管
2xx 成功
3xx 重定向
4xx 客户端的错误
5xx 服务器错误
http响应状态码全行业通用 只能表示这次请求的成功与否
4.业务状态码
业务状态码由后端程序员自定义,用来表示这次业务处理的成功与否,不具有通用性
只能在响应体看见
5.XMLHttpRequest
作用
浏览器内置的一个构造函数,基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求
步骤
1.创建xhr对象
2.xhr.open('请求的方式','请求的地址')
3.xhr.send()
4.监听数据响应 xhr.addEventListener('load', function () {
this.response//JSON字符串 });
const xhr = new XMLHttpRequest();
// 2 调用open方法 (指定请求的类型、指定请求的url)
xhr.open('GET', 'http://www.itcbc.com:3006/api/getbooks');
// 3 开始发起请求
xhr.send();
// 4 监听 数据响应
xhr.addEventListener('load', function () {
// 获取响应结果
// 本质上返回字符串类型是正确的
// axios别人封装的库, 别人帮我们重新把 JSON字符串 转成了对象而已
console.log(JSON.parse(this.response));
});
get请求携带参数
只能以键值对形式拼接在url?之后
const xhr=new XMLHttpRequest();
// 原生的ajax get请求 携带参数
xhr.open("GET","http://www.itcbc.com:3006/api/getbooks?bookname=传智亚瑟");
xhr.send();
xhr.addEventListener("load",function () {
console.log(this.response);
})
post请求携带参数setRequestHeader(请求头)
携带的参数只能放在xhr.send()
方法中
当send
携带参数时,需要在 xhr.open()
之后,xhr.send()
之前调用xhr.setRequestHeader()
函数,指定参数的编码格式,参数格式为formdata除外
xhr.send(参数=值&参数=值)--->xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
xhr.send(JSON字符串)--->xhr.setRequestHeader('Content-Type','application/json')
xhr.send(new FormData())--->不需要设置xhr.setRequestHeader()
ajax第四天
1.autocomplete="off"
添加在form标签上的属性, 关闭 form标签中的input标签的历史记录
2.form.reset()
重置form标签 讲form标签中的所有输入框内容情况
3.隐藏域
给input标签设置type='hidden'属性 用户即看不见这个输入框
ajax第五天
1.Nprogress
需要引入NProgress.css和NProgress.js
NProgress.js在axios.js之前引入
发送前显示等待中提示:NProgress.start()
响应回来关闭等待中提示:NProgress.done()
Nprogress一般在拦截器中使用
2.axios拦截器
请求拦截器
// 请求拦截器
axios.interceptors.request.use(function (config) {
// console.log("每一次发出请求的时候 触发 请求拦截器");
NProgress.start();
return config;
}, function (error) {
return Promise.reject(error);
});
响应拦截器
// 响应拦截器
axios.interceptors.response.use(function (response) {
// 数据 正常响应回来(状态码 200) 就会出触发
// console.log("正常响应回来(状态码 状态码200");
NProgress.done();
return response;
}, function (error) {
// 数据 也会回来(服务器返回错误提示信息 比如 404 500 )
// console.log("数据也响应 但是 状态码不正常");
NProgress.done();
return Promise.reject(error);
});
3.fetch(了解即可)
原生代码实现, 用于请求和响应服务器,跨网络异步获取资源
默认是get请求
fetch('http://www.itcbc.com:3006/api/getbooks').then(res => {
return res.json();
}).then(res => {
console.log(res);
})
post请求
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(res => {
return response.json(); objects;
}).then(res => {
console.log(res);
})
4.跨域和同源
是浏览器的一种安全机制, 同源指两个URL地址具有相同的协议, 主机号, 端口号, 不同源就是跨域
跨域了的两个url之间默认不让你们做数据交互
浏览器允许发起跨域请求, 但跨域请求回来的数据,会被浏览器拦截,无法被页面获取到
url默认端口号是80
http://www.test.com/index.html和http://www.test.com:80/main.html同源
解决跨域的方法:
CORS
cors跨域资源共享, 实现方式简单, 是跨域的主流技术解决方案(后端处理前端不干预)
支持 GET、POST、PUT、DELETE、PATCH等常见的请求方式, 不兼容某些低版本浏览器
服务器开启cors功能后, 响应标头会有 Access-Control-Allow-Origin : *
用到了 XMLHttpRequest 对象,发起的是纯正的 Ajax 请求
JSONP(了解即可)
JSONP 没有用到 XMLHttpRequest 对象, 不是真正的 Ajax 技术, 本质不是真正的跨域
JSONP只支持get请求
原理是利用了script标签天生不跨域的特点
利用script的src, 指定要加载的js文件, 服务器会在返回的js文件中藏着给你的数据
5.防抖
定义
频繁触发某个操作时,只执行最后一次, 只是一种代码技巧
应用场景
搜索框业务:用户输入完毕, 自动发出的一次请求
关键技术原理
延时器
实现过程
每一次输入时, 先清空上一次的延时器, 再开启一个新的延时器
<input type="text">
<script src="./axios.js"></script>
<script>
let timerId;
const input = document.querySelector('input');
input.addEventListener('input', function () {
clearTimeout(timerId);
timerId = setTimeout(function () {
axios.get('http://www.itcbc.com:3006/api/getbooks?appkey=hhh123456').then(res => {
console.log(res);
});
}, 2000);
})
</script>
6.节流
定义
单位时间内,频繁触发同一个操作,只会触发 1 次(第一次)
应用场景
射击游戏中,单位时间内只能发射一颗子弹
按钮的倒计时业务
手机验证码的倒计时业务
关键技术原理
是否允许业务条件(按钮禁用等)
实现过程
第一次点击, 先禁用按钮, 同时开启业务, 业务执行完毕, 重新启用按钮
<button>点我</button>
<script>
const btn = document.querySelector('button');
btn.addEventListener('click', function () {
btn.disabled = 1;
let num = 5;
let timerId = setInterval(function () {
num--;
console.log(num);
if (num === 0) {
clearInterval(timerId);
btn.disabled = 0;
}
}, 1000);
})
</script>