数据请求的四种方式
1.ajax 数据请求:
原生js提供的(内置),核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。
2.fetch 数据请求:
和ajax一样也是原生js提供的(内置),和ajax同级,使用promise形式,关注分离思想,但兼容性不太好,所以用的不是很多。
3. jquery数据请求:
封装原生的ajax请求,使用回调形式,可能回调地狱。(使用需要引入第三方库)
4. axios数据请求:
封装原生的ajax请求,使用promise的形式,并且可以在请求和响应阶段进行拦截。(使用需要引入第三方库)
关注点:使用原生ajax请求和使用axios请求
ajax 请求:
优点: 页面无刷新,用户体验好。异步通信,更加快的响应能力等等。
请求方式:get、post
1.get、post不同点:
(1).提交数据存储的位置不同 (安全性)
get请求将提交的数据拼接到URL后面?userName=lnj&userPwd=123456
(任何人可见)
post请求将数据放到请求头中(按f12=》Network=》header=》Form data)
(其他人不可见)
(2).提交数据大小限制不同
get请求对数据有大小限制 (适应于非敏感数据和小数据)
post请求对数据没有大小限制 (适应于敏感数据和大数据)
Ajax使用五个步骤:
1.创建一个XMLHttpRequest对象
var xmlhttp=new XMLHttpRequest();
2.设置请求方式和请求地址(使用open(method,url,async)方法)
method:请求方式,get或者post。(默认为get)
url:请求路径,文件在服务器上的位置
async:是否为异步请求。(默认为true,异步请求)
3.发送send() 请求
若为post方式时需要使用setRequestHeader()来添加http头
4.监听状态的变化
每当readyState状态改变时,就会触发 onreadystatechange事件,执行回调函数。
readyState存有XMLHttpRequest的5种状态。从 0 到 4 发生变化。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
5.处理返回的结果
根据请求服务器返回状态码(status)
大于200,小于300,或等于304,则表示请求成功, 否则服务器请求失败
获取服务器中响应,使用XMLHttpRequest对象的responseText或responseXML属性。
responseText : 获得字符串形式的响应数据。
responseXML : 获得 XML 形式的响应数据。
<button>发送请求</button>
<script>
window.onload=function () {
var btn =document.querySelector("button");
btn.onclick=function () {
//get请求
//1.创建一个异步对象
var xmlhttp=new XMLHttpRequest();
//2.设置请求方式和请求地址
xmlhttp.open("GET","07-Ajax-get.php"+"?userName=lnj&userPwd=123456",true);
//3.发送请求
xmlhttp.send();
//4.监听状态的变化
xmlhttp.onreadystatechange=function () {
if (xmlhttp.readyState === 4) {
//5.处理返回的结果
if (xmlhttp.status>=200 && xmlhttp.status<300 ||xmlhttp.status===304){
console.log(xmlhttp.responseText); //输出服务器响应的内容
}else{
console.log("没有接收到服务器的数据");
}
}
}
}
//post请求
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","10-Ajax-post.php",true);
//post方式时需要使用setRequestHeader()来添加http头,将该内容放在设置请求与发送请求之间;
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//发送请求, 将要提交的数据放在send()中;
xmlhttp.send("userName=liu&userPwd=654321");
xmlhttp.onreadystatechange=function () {
if (xmlhttp.readyState === 4) { //请求完成时响应;
if (xmlhttp.status>=200 && xmlhttp.status<300 ||xmlhttp.status===304 ){
console.log(xmlhttp.responseText);
}else{
console.log("没有接收到服务器的数据");
}
}
}
}
}
</script>
axios请求:
优点: Axios是轻量级的库,支持promise,可以拦截请求和响应等等。
安装: npm install axios
引入:import axios from “axios”
1.axios的基本使用:
axios()返回一个promise对象
//get
axios.get('http://123.207.32.32:8000/home/data?type=sell&page=3')
.then((response)=> { console.log(response)})
.catch((error)=> {console.log(error)})
可以通过向 axios 传递相关配置的方式来创建请求,如下:
axios({
methods:"get" //请求方式不写就默认为get请求
url:"http://123.207.32.32:8000/home/data?type=sell&page=3",
}).then(res=>{ //数据请求成功,res为成功数据
console.log(res);
}).catch((err)=>{
console.log(error);
)
//可以将url拆分开,将后面的参数单独放在params中
axios({
methods:"get"
url:"http://123.207.32.32:8000/home/data",
params:{
type:"sell",
page:3
}
}).then(res=>{ //请求成功
console.log(res);
})
//post
axios({
method: 'post',
url: '/user/12345',
data: { //post传递参数
firstName: 'Fred',
lastName: 'Flintstone'
}
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
2.axios发送并发请求
axios.all([ axios(),axios() ]) .then(results => { … })
axios.all([ //第一个请求
axios({
url:"http://123.207.32.32:8000/home/multidata"
}),
axios({ //第二个请求
url:"http://123.207.32.32:8000/home/data",
params: {
type:"sell",
page:5
}
})
]).then(results => { //results为数组,存是两次请求成功的数据
console.log(results); //将整个数组输出
console.log(results[0]);
console.log(results[1]);
})
3.axios全局配置
在axios请求中,可以设置超时时间
axios.all([
axios({
// url:"http://123.207.32.32:8000/home/multidata", url分解为
baseURL:"http://123.207.32.32:8000",
url:"/home/multidata",
timeout:5000 //超时时间
}),
axios({
url:"http://123.207.32.32:8000/home/data",
timeout:5000
})
]).then(results => {console.log(results)})
//若每个axios的超时时间和baseURL都相同 就可以进行全局配置,让所有的axios请求都会使用全局配置发送请求。(公共的对象放在全局配置里面)
//全局配置内容
axios.defaults.baseURL="http://123.207.32.32:8000"
axios.defaults.timeout=5000
axios.all([
axios({
url:"/home/multidata",
}),
axios({
url:"/home/data",
})
]).then(results => {console.log(results) })
4.创建axios实例
有时候请求不想用全局配置的内容,则我们可以创建axios实例,在该axios实例中全局配置,则只在该实例内有效。
const instance = axios.create({
baseURL:"http://123.207.32.32:8000",
timeout:5000
})
// 在instance实例中发送请求,则会使用instance实例的axios配置。
instance({
url:"/home/multidata"
}).then(res => {
console.log(res);
})
//
instance({
url:"/home/data",
params:{
type:"pop",
page:1
}
}).then(res=>{
console.log(res);
})
5.封装一个request模块
为了可以让主页面的代码尽量少一些,可以封装一个request模块,在模块中封装好axios的网络请求,然后直接引入使用。
request模块中封装:
(推荐方式2)
//方式1:
export function request(config ,success ,failure) {
//1.创建axios实例
const instance = axios.create({
baseURL:"http://123.207.32.32:8000",
timeout:5000
})
//2.发送网络请求
instance (config) //config为传进来的参数。
.then(res =>{
console.log(res);
success(res); //success为传进来的函数,则res外函数的参数。
}).catch(err=>{
console.log(res);
failure(res); //传参
})
}
//方式2:
export function request(config) {
//1.创建axios实例
const instance = axios.create({
baseURL:"http://123.207.32.32:8000",
timeout:5000
})
return instance (config)
//axios返回的是一个promise对象,return instance实例, 所以prmose中的res数据为该实例。
//这里是直接将instance实例返回给主页面,然后在主页面中进行操作。
}
主页面中:
//方式1:
request({ //为request()传过去3个参数。
url:"/home/multidata"
},res =>{ //则这里res是success(res)中res,是拿到的结果
console.log(res);
},err=>{
console.log(err);
})
//方式2:
//传入url, 返回instance实例, 然后在该页面对结果进行处理
request({
url:"/home/multidata"
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
6.拦截器:
拦截axios的请求和响应,可以在请求数据前和拿到响应返回数据前添加一些代码,然后进行相应的处理。可以转换请求数据和响应数据
request模块中封装:
export function request(config) {
//1.创建axios实例
const instance = axios.create({
baseURL:"http://123.207.32.32:8000",
timeout:5000
})
//2.axios的请求拦截器, 拦截的是instance请求中的config内容。
instance.interceptors.request.use(config =>{
//这里的config包含每次请求的内容,如请求头、url、传参data等等。
console.log(config);
//请求拦截后会做什么事情???
//1.比如:config中的一些信息,不符合服务器的要求, 对信息修改会转化
//2.比如:某些网络请求(登录..),必须携带一些特殊的信息,则将它拦截,然后判断一下,如果没带特殊信息,则给它提示
return config
//请求拦截,操作后返回config,不然请求拦截了服务器不会响应,拿不到结果。
},err => {
console.log(err);
})
//3.axios的响应拦截器, 拦截的是服务器返回的结果res
instance.interceptors.response.use(res=>{
//这里的res包含服务器响应的data、响应头、状态码,配置等等。
console.log(res);
//拦截后,进行相关操作...
return res.data
//若需要数据,则可以只返回拦截内容中的data就可以了
},err=>{
console.log(err);
})
return instance (config)
}
axios的请求拦截器中的config对象中内容
axios的响应拦截器中的res对象中内容
主页面中:
request({
url:"/home/multidata"
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
扩展:
HTTP请求报文由3部分组成 =>(请求行+请求头+请求体)
请求头 存放通知服务器有关于客户端请求的信息,一般用来存放一些cookie,token等信息(属性:属性值)
常见的请求头有:
cookie : 浏览器端cookie
Accept :告诉服务端 客户端接受什么类型的响应。
Authorization HTTP授权的授权证书 ——》用来设置token
Referer:表示这个请求是从哪个URL过来的
application/json : JSON数据格式
Connect-Type : 显示此HTTP请求提交的内容类型。一般只有post提交时才需要设置该属性。等等。
响应头 Response Header
常见的响应头有:
Accept-Ranges:表明服务器是否支持指定范围请求及哪种类型的分段请求
Expires:响应过期的日期和时间
常见的响应码有:
1. 200 OK
2. 303 See Other ,把redirect到其它的页面
3. 404 Not Found ,责任在客户端 ,即找不到页面
4 .5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错等
7.拦截器实例:
扩展:token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,来进行验证客户端的权限等。
登录token的验证流程:
1.客户端使用用户名跟密码请求登录,服务端收到请求,去验证用户名与密码
3.验证成功后,服务端会想客户端返回一个 token
4.客户端收到 token后把它存在浏览器的 sessionStorage 或者 localStorage 中
5.客户端每次向服务端请求资源时携带token验证,(获取 localStorage中存储的token,将它放在请求头中)
6.服务端收到请求,然后去验证客户端请求里面带着的 token,如果验证成功,就向客户端返回请求的数据
1.在登陆的时候后台会给一个token码,前台将其存储在浏览器的cookie,localstroage或localsession中
login(){
axios.post('/user/login',this.user).then((res)=>{
localStorage.setItem('token',"Bearer "+res.data.res.token)
//需要在token的前边拼接字符串’Bearer '+,固定格式
})
}
发起请求时带上token,看用户是否有权限
const token = window.sessionStorage.getItem('cat_token') //获取存储的token
axios.get('path', {
headers: {
authorization: `Bearer ${token}`, //将token放到请求头中,Authorization属性存放验证
},
});
拦截器中处理token
请求时将token放入请求头,响应是若token过期,则根据返回的错误码提示
// http request 拦截器
axios.interceptors.request.use(
config => {
if (localStorage.token) { //判断token是否存在
config.headers.Authorization = localStorage.token; //将token放入请求头
}
return config;
},
err => {
return Promise.reject(err);
}
);
// http response 拦截器
axios.interceptors.response.use(
response => {
if (response.data.errno === 999) { //过期服务器返回错误码
router.replace('/');
console.log("token过期");
}
return response;
},
error => {
return Promise.reject(error);
}
);
export default axios;
(注:若有不需要验证的页面 或者 没有权限的设置为不能进入该页面 则可以在路由配置中限制)
点击,token参考文档,axios拦截器,实现token认证
token过期处理:
1.返回到登录页面 ,重新请求登录返回token
2.通过时间判断是否快过期,然后自动刷新token,若刷新失败返回登录页面。
自动刷新:请求前用refleshToken()接口来请求,返回新的token,再用新的token将旧的替换,不影响后面操作。
什么时候自动刷新???
在登录返回token值时前台获取当前时间戳,设置距离过期还有多长时间时自动刷新,
(登录的时候后端返回一个token过期时间(秒),转换成时间戳保存下来。在拦截器中获取当前的时间,进行对比。点击案例)