什么是ajax?
ajax全称为Asynchronous Javascript And XML,它是一种技术,实现了前后端交互的方式,有利于前后端更好的分离。可以使页面局部刷新,对用户更加友好。
原生ajax
let xhr = new XMLHttpRequest;
//open(参数1,参数2) 参数1指的是 请求的方式(GET,POST) 参数2指的是请求的地址(接口)
/*
请求方式:
get系列:get delete...
post系列:post put option...
*/
xhr.open('GET', './data.json', true); //true异步 false同步
/*
readyState:请求状态
done:4 完成请求
headers_recelved:2 已经接收了 响应头部信息
loading:3 正在接收响应体
opened:1 执行过open之后变成
unsent:0
*/
xhr.onreadystatecahnge = function(){
let {readyState,status,response} = xhr;
if (readyState === 4 && status === 200) {
console.log(response);
}
};
xhr.send();
对ajax进行封装
(function() {
class ajax {
constructor(obj) {
this.obj = obj;
this.obj = {
method: 'get', //请求方式
url: '', //接口地址
data: {}, //要传递的参数
catchs: true, //默认走缓存
success() {}, //成功回调函数
error() {}, //失败回调函数
...this.obj //赋予默认值
}; //赋默认值
let {url,method,data,success,error,catchs} = this.obj;
this.str = ``;
if (!catchs && /get/i.test(this.obj.method)) {
//catchs 为 false 并且请求方式为get 在要传的参数中添加一个当前时间戳 防止走缓存
this.obj.data.____ = Date.now();
}
if (/get/i.test(this.obj.method)) {
//如果是get请求就将参数拼接到url后面
Object.keys(this.obj.data).forEach(item => {
this.str += `${item} = ${this.obj.data[item]}&`;
this.str = this.str.replace(/\&$/, '')
})
//在前面加上?
this.str = '?' + this.str;
};
//将url和参数拼接到一起
this.url = url + this.str;
this.xhr = new XMLHttpRequest();
this.xhr.open(method, this.url);
this.xhr.onreadystatechange = () => {
let {readyState,status,response} = this.xhr;
if (readyState === 4 && status === 200) {
this.data = response;
this.obj.success(this.data);
} else if (readyState === 4 && /[45]\d{2}/.test(status)) {
this.obj.error(new Error('请求出错'));
}
}
this.xhr.setRequestHeader('content-Type', 'application/x-www-form-urlencoded')
this.xhr.send(this.str != '' ? this.str : JSON.stringify(this.obj.data));
//send传递的参数只对post请求起作用
}
}
//暴露API
window.ajax = ajax;
const get = function get(obj) {
obj = {
data: {},
...obj
}
let {url, success, error,data} = obj;
new ajax({
url: url,
data: data,
caches: true,
success: success,
error: error,
method: 'get'
});
};
const post = function post(obj) {
obj = {
data: {},
...obj
}
let {url,success,error, data} = obj;
new ajax({
url: url,
data: data,
success: success,
method: 'post',
error: error,
caches: false,
});
}
window.get = get;
window.post = post;
})();
前端的存储
localStorage
//存储
localStorage.setItem('name',要存储的值);
//获取
localStorage.getItem('name');
//移除
localStorage.removeItem('name');
sessionStorage
//存储
sessionStorage.setItem('name',要存储的值);
//获取
sessionStorage.getItem('name');
//移除
sessionStorage.removeItem('name');
cookie
//获取
document.cookie('name');
//设置
document.cookie('name',要存储的值);
//移除 目前没有提供删除方法,但是可以把它的Max-age设置为0,也就是立马失效,也就是删除了
三者的区别
localStaorage的生命周期很长,即使页面关闭也不会消失,只要不删除,就会一直存在。容量大小为5MB,作用域:只要是在同一浏览器即使在不同标签下,只要是同源的情况下,都可以使用。
sessionStaorage 的生命周期:在浏览器或者页面关闭就会消失,作用域 只在当前页面可用 容量同样为5MB
cookie是保存在客户端的,一般由后端设置值,可以设置过期时间 容量只有4KB 一般是用来存储用户信息的
在http下cookie是明文传输的(发送请求默认携带cookie) 不安全
cookie属性有
http-only:不能被客户端更改访问,防止XSS攻击(保证cookie安全性的操作)
Secure:只允许在https下传输
Max-age:cookie生成后失效的秒数
expire: cookie的最长有效时间,若不设置则cookie生命期与会话期相同
localStorage 方法封装
设置一套具备有效周期的LocalStorage存储方案:存储信息的时候多设置一个时间;获取信息的时候;首先获取时间,在和当前时间做对比较手动计算是否超过了限定的周期;如果没有超过,说明存储的信息有效,我们拿过来使用即可! 如果超过了 说明存储的信息已经过期 我们把其清除掉,并且从服务器重新获取数据
const Storage = {
//存储信息:记录存储时间
set(name, data) {
localStorage.setItem(name, {
time: +new Date,
data
})
},
//获取信息:做有效性的检测 limit我们设定的存储周期(单位:毫秒)默认一小时
get(name, limit = 3600000) {
let temp = localStorage.getItem(name);
if (temp) {
let {time,data} = temp;
if (+new Date() - time <= limit) {
//信息在有效期内
return data;
};
//无效:移除存储的信息
};
return null;
},
//移除信息
remove(name) {
localStorage.removeItem(name);
}
}
HTTP结构-请求报文
通用头:General: Request URL:请求的接口地址 Requst Method:请求方式 Status Code:本次请求的状态码
200:成功
301:重定向 永久
302:重定向 临时
304:缓存 向后端请求数据 后端没有返回新数据 即可使用之前缓存
403:访问被拒绝
404:访问路径出错
405:访问的方式出错
5xx 一般都是服务端错误
请求头:Request Headers,是请求发送的时候前端带给后端的一些信息,前端可以设置,后端设置不了
access-control-allow-origin 是否支持跨域 * 表示支持跨域
cache-control:当前是否使用缓存
Connection:keep-alive 与服务器的连接状态
Host 主机域
响应头:Response Headers,是请求回来的时候后端带给前端的一些信息,响应头是后端设置的,前端只能看 不能动
cache-control
etag 唯一标识,缓存用的
last-modified最后修改时间
设置请求头
setRequestHeader设置请求头中的属性,getRequestHeader获取请求头中的属性,getAllRequestHeader获取全部请求头属性。
let xhr = new XMLHttpRequest;
xhr.open('GET', './data.json', true);
xhr.onreadystatecahnge = function(){
let {readyState,status,response} = xhr;
if (readyState === 4 && status === 200) {
console.log(response);
}
};
xhr.setRequestHeader('content-Type', 'application/x-www-form-urlencoded')//必须写在send前面
xhr.send();
获取响应头
getResponseHeader获取响应头,getAllResponseHeader获取全部响应头
GET和POST的区别
GET请求 主要用来从服务器获取数据,传参方式为在url后面进行拼接,所以传参的大小会有限制,GET请请求会有缓存, POST请求 主要用来向服务端传递数据,传参方式为放在请求头中(放在send()中),所以传递的参数的长度不会被限制,POST请求没有缓存,POST请求比GET请求更加安全
传递参数
如果后端需要JSON格式的请求体 那么我们需要把参数转为JSON格式字符串 传递给send 同时一般需要设置 请求头中的 content-type 为application/json
如果后端需要formData格式的请求体 那么我们需要把参数转为formData格式的字符串 传递给send 同时一般需要设置 请求头中的 content-type 为 application/x-www-form-urlencoded
HTTP缓存
HTTP的缓存分为强缓存和协商缓存
强缓存:客户端请求数据之前会先经过缓存 如果有缓存就不会再去服务器请求数据 直接使用缓存
在浏览器加载资源时,先看看cache-control里的max-age,判断数据有没有过期,如果没有直接使用该缓存 ,有些用
户可能会在没有过期的时候就点了刷新按钮,这个时候浏览器就回去请求服务端,要想避免这样做,可以在cache-
control里面加一个immutable.
public 允许客户端和虚拟服务器缓存该资源,cache-control中的一个属性
private 只允许客户端缓存该资源
no-cache 不允许强缓存,可以协商缓存
no-store 不允许缓存
协商缓存就是强制缓存失效后或者强缓存未命中
响应头
last-modified:web,27 Apr 2022 08:37:30 GMT
etag:W/"11a6f3c6fa0c19a7b4270dea6138b20c"
请求头
if-modified-since:web 27 Apr 2022 08:37:30 GMT
服务器在给资源的时候 会同时给上个资源的修改时间 或者 一个标识
以后我们前端再去服务端请求资源的时候 会带上这个修改时间或者标识
浏览器加载资源时,没有命中强缓存,这时候就去请求服务器,去请求服务器的时候,会带着两个参数,一个是If-
None-Match,也就是响应头中的etag属性,每个文件对应一个etag;另一个参数是If-Modified-Since,也就是响应
头中的Last-Modified属性,带着这两个参数去检验缓存是否真的过期,如果没有过期,则服务器会给浏览器返回一
个304状态码,表示缓存没有过期,可以使用旧缓存。
etag的作用
有时候编辑了文件,但是没有修改,但是last-modified属性的时间就会改变,导致服务器会重新发送资源
,但是etag的出现就完美的避免了这个问题,他是文件的唯一标识
缓存位置:
- 内存缓存Memory-Cache
- 离线缓存Service-Worker
- 磁盘缓存Disk-Cache
- 推送缓存Push-Cache
清除缓存
为什么要清除缓存?
有时候我们需要每次从服务端获取到的都是最新的数据,这时候我们就不能让浏览器从缓存中获取数据
实现方法 在url上补充一个每次不一样的一个参数即可 因为参数若不同 浏览器会理解成两个不同地址 就不会再去缓存去获取内容了
axios
axios是一个基于Promise和Ajax封装的插件,可以帮助我们更加方便的管理ajax请求,是一款比较常用的插件,执行结果为一个promise实例,我们可以直接使用then和catch接收。
使用axios进行get请求,参数需要传递在第二个参数中的pamas中(第一个参数为接口地址,第二个参数为一个对象)
axios.get('https://baidu.com/list',{
pamas:{
aa:1,
bb:2
}
}).then(response=>{
console.log(response);
}).catch(err=>{
console.log(err);
)
使用axios进行post请求,参数直接写在第二个参数中即可
axios.post('https://baidu.com/list',{
aa:1,
bb:2
}).then(response=>{
console.log(response);
}).catch(err=>{
console.log(err);
)
我们可以使用axios统一配置请求地址和请求头
axios.defaults.baseURL='https://baidu.com';//设置地址 后续请求只需要写此域名后的接口地址即可
axios.defaults.headers.common['aaa'] = 123;//设置请求头 在请求头中添加属性
设置请求拦截器和响应拦截器
我们可以在请求拦截器中设置统一的请求标头,在响应拦截器中我们可以进行数据的处理。
axios.interceptors.request.use(config=>{
config.headers.aaa = 666888; //设置请求标头
});
axios.interceptors.response.use(response=>{
return response.data
})