您好,登錄后才能下訂單哦!
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(); } }) }
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。