Vue axios实现获取token临时令牌封装?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
函数声明
getToken:从本地取已存储token
checkToken:检查token时效,失效调用refreshToken函数成功则存储本地,否则返回错误原因
refreshToken:调用JS方法从App获取签名参数重新请求token
注意事项
在checkToken过程中token过期时,先移除本地已过期token缓存数据。
/* eslint-disable no-console */
/* eslint-disable no-unused-vars */
"use strict";
import Vue from 'vue';
import axios from "axios";
import { getToken } from '../utils/storage.js'
import { checkToken, refreshToken, clearCache } from "../utils/utils.js";
// Full config: https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.headers.post["Content-Type"] = "application/json";
let cancel,
promiseArr = {};
let config = {
baseURL: process.env.VUE_APP_BASE_URL,
timeout: 8 * 1000, // Timeout
withCredentials: true, // Check cross-site Access-Control
};
const _axios = axios.create(config);
_axios.interceptors.request.use(
function (config) {
// Do something before request is sent
let token = getToken();
// alert("token1:" + token);
//发起请求时,取消掉当前正在进行的相同请求
if (promiseArr[config.url]) {
promiseArr[config.url]("请稍后");
promiseArr[config.url] = cancel;
} else {
promiseArr[config.url] = cancel;
}
if (token) {
return checkToken(null)
.then((result) => {
// console.log("refreshToken result:", result);
if (result === true) {
token = getToken()
// alert("token2:" + token);
config.headers.common["authorization"] = token;
return config;
} else {
return Promise.reject(Error(result))
}
}).catch((err) => {
// 终止这个请求
return Promise.reject(err);
});
}
return config;
},
function (error) {
// Do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
_axios.interceptors.response.use(
function (response) {
// Do something with response data
let { status, statusText, data } = response;
if (err_check(status, statusText, data) && data) {
// var randomColor = `rgba(${parseInt(Math.random() * 255)},${parseInt(
// Math.random() * 255
// )},${parseInt(Math.random() * 255)})`;
// console.log(
// "%c┍------------------------------------------------------------------┑",
// `color:${randomColor};`
// );
// console.log("| 请求地址:", response.config.url);
// console.log("| 请求参数:", response.config.data);
// console.log("| 返回数据:", response.data);
// console.log(
// "%c┕------------------------------------------------------------------┙",
// `color:${randomColor};`
// );
if (data.resCode === "0001") {
clearCache()
var config = response.config;
var url = config.url;
url = url.replace("/apis", "").replace(process.env.VUE_APP_BASE_URL, "")
config.url = url;
// alert(JSON.stringify(config))
return refreshToken(null)
.then((result) => {
// console.log("refreshToken result:", result);
if (result == true) {
let token = getToken()
if (token) {
config.headers["authorization"] = token;
}
return axios(config)
.then((result) => {
let { status, statusText, data } = result;
// console.log('接口二次请求 result:', result);
if (err_check(status, statusText, data) && data) {
return Promise.resolve(data)
} else {
return Promise.reject(Error(data.resDesc));
}
}).catch((err) => {
// console.log('接口二次请求 err:' + err);
return Promise.reject(err);
});
} else {
// alert("result:" + result)
return Promise.reject(Error(data.resDesc))
}
}).catch((err) => {
// 终止这个请求
// alert("终止这个请求:" + err.message)
// console.log("refreshToken err:", err);
return Promise.reject(err);
});
} else {
return Promise.resolve(data);
}
} else {
return Promise.reject(Error(statusText));
}
// return response;
},
function (error) {
// Do something with response error
// console.log("error", error);
return Promise.reject(error);
}
);
// eslint-disable-next-line no-unused-vars
const err_check = (code, message, data) => {
if (code == 200) {
return true;
}
return false;
};
Plugin.install = function (Vue, options) {
Vue.axios = _axios;
window.axios = _axios;
Object.defineProperties(Vue.prototype, {
axios: {
get() {
return _axios;
}
},
$axios: {
get() {
return _axios;
}
},
});
};
Vue.use(Plugin)
export default Plugin;
补充知识:vue+ axios+token 封装axios 封装接口url,带token请求,token失效刷新
一、封装axios
import axios from 'axios'
import qs from "qs"
const TIME_OUT_MS = 60 * 1000 // 默认请求超时时间
//axios.defaults.baseURL = 'http://localhost:8080';
// http request 拦截器
axios.interceptors.request.use(
config => {
if ($cookies.get("access_token")) { // 判断是否存在token,如果存在的话,则每个http header都加上token
config.headers.Authorization ='Bearer '+ $cookies.get("access_token");
}
return config;
},
err => {
return Promise.reject(err);
});
// http response 拦截器
axios.interceptors.response.use(
response => {
return response;
},
error => {
console.log("response error :"+error);
if (error.response) {
switch (error.response.status) {
case 401:
console.log("token 过期");
var config = error.config;
refresh(config);
return;
}
}
return Promise.reject(error) // 返回接口返回的错误信息
});
/*
*刷新token
*/
function refresh(config){
var refreshToken = $cookies.get("refresh_token");
var grant_type = "refresh_token";
axios({
method: 'post',
url: '/oauth/token',
data: handleParams({"grant_type":grant_type,"refresh_token":refreshToken}),
timeout: TIME_OUT_MS,
headers: {}
}).then(
(result) => {
if(result.data.access_token){ //重新保存token
$cookies.set("access_token",result.data.access_token);
$cookies.set("refresh_token",result.data.refresh_token);
//需要重新执行
axios(config);
}else{
//this.$events.emit('goto', 'login');
window.location.reload();
}
}
).catch((error) => {
//this.$events.emit('goto','login');
window.location.reload();
});
}
/*
* @param response 返回数据列表
*/
function handleResults (response) {
var result = {
success: false,
message: '',
status: [],
errorCode: '',
data: {}
}
if (response.status == '200') {
result.status = response.status;
result.data = response.data;
result.success = true;
}
return result
}
// function handleUrl (url) {
// //url = BASE_URL + url
// url =root +url;
// // BASE_URL是接口的ip前缀,比如http:10.100.1.1:8989/
// return url
// }
/*
* @param data 参数列表
* @return
*/
function handleParams (data) {
return qs.stringify(data);
}
export default {
/*
* @param url
* @param data
* @param response 请求成功时的回调函数
* @param exception 异常的回调函数
*/
post (url, data, response, exception) {
axios({
method: 'post',
//url: handleUrl(url),
url: url,
data: handleParams(data),
timeout: TIME_OUT_MS,
headers: {
//'Content-Type': 'application/json; charset=UTF-8'
}
}).then(
(result) => {
response(handleResults(result))
}
).catch(
(error) => {
if (exception) {
exception(error)
} else {
console.log(error)
}
}
)
},
/*
* get 请求
* @param url
* @param response 请求成功时的回调函数
* @param exception 异常的回调函数
*/
get (url,data, response, exception) {
axios({
method: 'get',
url: url,
params:data,
timeout: TIME_OUT_MS,
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
}).then(
(result) => {
response(handleResults(result))
}
).catch(
(error) => {
console.log("error"+response);
if (exception) {
exception(error)
} else {
console.log(error)
}
}
)
}
}
二、配置axios 跨域,以及请求baseUrl
1.config-->index.js
'
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
//引入跨域配置
var proxyConfig = require('./proxyConfig')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
//proxyTable: {}, //默认跨域配置为空
proxyTable: proxyConfig.proxy,
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8886, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
// 项目名字改变时这里需要变化 原先为assetsPublicPath: '.'
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
2.config目录下创建一个文件 proxyConfig.js文件
module.exports={
proxy:{
'/':{ //将localhost:8081 映射为 /apis
target:'http://localhost:8080',//接口地址
changeOrigin: true,// 如果接口跨域,需要进行这个参数配置
secure:false, //如果接口是HTTPS接口,需要设置成true
pathRewrite:{
'^/':''
}
}
}
}
三、封装API 请求Url port.js
export default {
oauth: {
login: '/oauth/token', // 登录
logout: '/oauth/logout' // // 退出
},
user: {
addUser: '/user/add',
updateUser: '/user/update',
getUser:'/user/', //+ Id
exists:'/exists/', // +id
enable:'/enable/', // +id
disable:'/disable/', // +id
delete:'/delete/', //+id
password:'/password ',
query:'/query'
}
}
四、main.js 引入
import http from './plugins/http.js'
import ports from './plugins/ports'
Vue.prototype.http = http
Vue.prototype.ports = ports
五、使用
login.vue中使用
login() {
this.http.post(this.ports.oauth.login,{username:this.userId,
password:this.password,grant_type:'password'}, res => {
if (res.success) {
// 返回正确的处理
页面跳转
this.$events.emit('goto', 'edit');
} else {
// 返回错误的处理
//alert("等待处理");
}
},err =>{
//console.log("正在处理"+err.response.status);
if(err.response.status=='400'){
//显示用户名或密码错误
this.$refs.username.focus();
this.$refs.hint.click();
}
})
}
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。