主要文件
src/utils/download.js
import request from './request'
export function download(url, params,filename) {
request({
method: 'get',
params: params,
url: url,
responseType: 'blob',
timeout: 0
}).then(res => {
resolveBlob(res, filename)
}).catch((error) => {
console.log(error)
for (let e in error) {
console.log(e, error[e])
}
});
}
function resolveBlob(res, fileName) {
const aLink = document.createElement('a')
let blob = new Blob([res.data])
if (!fileName) {
//if not set filename, getting from response header, match regExp:
// response.setHeader("Content-disposition", "attachment; filename=sample.docx"); or
// response.setHeader("Content-disposition", "attachment; filename*=utf-8''sample.docx");
let regExp = new RegExp('filename(?:=|\\*=.+\'\')([^;]+\.[^\.;]+);*');
let contentDisposition = decodeURI(res.headers['content-disposition'])
let result = regExp.exec(contentDisposition)
if (result && result.length > 1 ) {
fileName = result[1]
fileName = fileName.replace(/\"/g, '')
} else {
fileName = new Date().getTime();
}
}
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName);
} else {
aLink.href = URL.createObjectURL(blob)
aLink.setAttribute('download', fileName) // 设置下载文件名称
aLink.click()
window.URL.revokeObjectURL(aLink.href);
}
}
/src/utils/request.js
import axios from 'axios'
import qs from 'qs'
import {Message} from 'element-ui'
import md5 from 'js-md5'
import {getToken, getAccessToken} from "@/utils/auth";
import router from "@/router";
import store from "@/store";
import APP_CONFIG from "../config/config";
/** http error */
const HTTP_ERROR = {
UNAUTHORIZED: {
code: 401,
msg: '请求未授权',
},
FORBIDDEN: {
code: 403,
msg: '无权查看',
},
NOT_FOUND: {
code: 404,
msg: '请求地址不存在',
},
METHOD_NOT_ALLOWED: {
code: 405,
msg: '请求方式不支持',
},
NOT_ACCEPTABLE: {
code: 406,
msg: '请求被拒绝',
},
LENGTH_REQUIRED: {
code: 411,
msg: '长度受限',
},
UNSUPPORTED_MEDIA_TYPE: {
code: 415,
msg: '不支持的媒体类型',
},
SERVER_ERROR: {
code: 500,
msg: '服务器错误'
},
BAD_GATEWAY: {
code: 502,
msg: '服务器未响应'
},
SERVICE_UNAVAILABLE: {
code: 503,
msg: '当前服务暂不可用'
},
UNKNOWN: {
code: 996,
msg: '未知错误'
},
NETWORK_ERROR: {
code: -1,
msg: '网络错误'
}
}
/**sign key**/
const SIGN_KEY = '123456789';
/**
* sort & serialize query
* @param arg
* @returns {string}
*/
function prepareQuery(arg) {
const names = Object.keys(arg).sort()
let ret = ''
for (let i = 0; i < names.length; ++i) {
const name = names[i]
const val = arg[name]
if (val === false) {
ret += (name + '0')
} else if (val === true) {
ret += (name + '1')
} else if (typeof val === 'number') {
ret += (name + val)
} else if (typeof val === 'string') {
ret += (name + val)
} else if (Array.isArray(val)) {
ret += (name + val.join(','))
} else if (val) {
ret += (name + JSON.stringify(val))
} else {
ret += name
}
}
return ret
}
/**
* show error tips with element ui message component
* @param cfg
*/
function showErrorMessage(cfg) {
Message({
message: cfg.msg,
type: 'error',
duration: 5 * 1000
})
}
/**
* check token valid, if token expired ,refresh token
*/
function checkToken() {
let token = getToken();
if (token && isTokenNeedRefresh(token)) {
refreshToken();
}
}
/**
* check token expired time, if left time < expired/5, refresh token
* @param token
* @returns {boolean|boolean}
*/
function isTokenNeedRefresh(token) {
let now = new Date().getTime();
let expiredTime = token.ts + (token.expired * 1000);
let time = expiredTime - now;
return time > 0 && time < (token.expired / 5 * 1000)
}
/**
* refresh token
* simple implements, use old token to get new token
*/
function refreshToken() {
const time = String(new Date().getTime())
axios.get(baseURL + "/auth/refresh", {
headers: {
Authorization: getAccessToken(),
sign: md5(SIGN_KEY + time),
timestamp: time
}
}).then((res) => {
if (res.status === 200) {
if (res.data && res.data.code === 200 && res.data.data) {
let tokenObj = {
token: res.data.data.token,
expired: res.data.data.expired,
ts: new Date().getTime()
}
store.dispatch("user/setUserToken", tokenObj)
} else {
processSystemError(res)
}
}
}).catch((error) => {
processHttpError(error)
});
}
/**
* show system error message
* @param response
*/
function processSystemError(response) {
let cfg = {
code: response.data.code,
msg: response.data.msg,
}
showErrorMessage(cfg);
if (response.data.code === 601) {
router.push({
path: '/login'
});
}
}
/**
* show http error message
* @param error
*/
function processHttpError(error) {
let httpError = HTTP_ERROR.NETWORK_ERROR;
if (error.response) {
for (const httpStatus in HTTP_ERROR) {
let e = HTTP_ERROR[httpStatus];
if (e && e.code === error.response.status) {
httpError = e;
break;
}
}
}
showErrorMessage(httpError);
}
const baseURL = APP_CONFIG.VUE_APP_API_HOST_DEFAULT;
const service = axios.create({
baseURL: baseURL, // url = base url + request url
withCredentials: false, // do not need cookie
timeout: 1000 * 10
})
/** request interceptor */
service.interceptors.request.use(
config => {
// refresh token if expired
checkToken(config);
let serializedData = '';
if (config.method === 'get' || config.method === 'delete') {
if (config.params && Object.getOwnPropertyNames(config.params).length) {
serializedData = prepareQuery(config.params);
// array params formatter, a:[1,2,3] => a=1,2,3
config.paramsSerializer = function (params) {
return qs.stringify(params, {arrayFormat: 'comma'})
}
}
} else {
if (config.data && !(config.data instanceof FormData)) {
serializedData = JSON.stringify(config.data);
}
}
const time = String(new Date().getTime())
config.headers['timestamp'] = time
config.headers['sign'] = md5(SIGN_KEY + time + serializedData)
let accessToken = getAccessToken();
if (accessToken) {
config.headers['Authorization'] = accessToken;
}
return config
},
error => {
return Promise.reject(error)
}
)
/** response interceptor **/
service.interceptors.response.use(
response => {
if (response.status === 200) {
// pre-processing json response
if (response.headers['content-type'].indexOf("application/json") != -1) {
if (response.data.code === 200) {
return response.data
}else if(getToken().token === "mock"){
return response.data
} else {
processSystemError(response)
return Promise.reject(response.data)
}
} else {
return Promise.resolve(response);
}
}
},
error => {
processHttpError(error);
return Promise.reject(error)
}
)
export default service
src/utils/auth.js
const TOKEN_KEY = 'token'
export function getAccessToken() {
const ret = sessionStorage.getItem(TOKEN_KEY)
const obj = JSON.parse(ret);
return obj ? obj.token : '';
}
export function getToken() {
const ret = sessionStorage.getItem(TOKEN_KEY)
return JSON.parse(ret);
}
export function setToken(token) {
sessionStorage.setItem(TOKEN_KEY, JSON.stringify(token))
}
export function removeToken() {
sessionStorage.removeItem(TOKEN_KEY)
}
config/config.js
const APP_CONFIG = {
NODE_ENV: process.env.NODE_ENV,
VUE_APP_API_HOST_DEFAULT: process.env.VUE_APP_API_HOST_DEFAULT,
VUE_APP_DATAVIEW_LOGIN_URL: process.env.VUE_APP_DATAVIEW_LOGIN_URL,
VUE_APP_WS_URL: process.env.VUE_APP_WS_URL,
VUE_APP_BPM_URL: process.env.VUE_APP_BPM_URL
}
export default APP_CONFIG;