文章目录
- 系列文章目录
- 前言
- 一、基于vue+elementui+admin对axios进行封装?
- 二、使用步骤
- 1.若项目需要进行字符防串改处理(项目需要而定)
- 2.创建crypto.js和encrypt.js
- 总结
一、封装axios是什么?
在创建utils文件夹下在创建https.js
import axios from 'axios'
import router from '@/router'
import { MessageBox, Message, Loading, Notification } from 'element-ui'
import Qs from 'qs'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { dataSort, md5, aes, sign, aesEn, aesDe } from "./crypto";
import { RSAencrypt } from "./encrypt"
const _MessageBox = MessageBox
const { alert, confirm, prompt } = _MessageBox
const loginUrl = '/login'
let loadingInstance = null // 加载全局的loading
// 根据环境切换接口地址
// axios.defaults.baseURL = process.env.VUE_APP_BASE_API
// axios.defaults.headers = { 'X-Requested-With': 'XMLHttpRequest' }
// axios.defaults.timeout = 60000
const service = axios.create(
{ //创建axios实例,在这里可以设置请求的默认配置
timeout: 60000, // 设置超时时间60s 247 207 239
// baseURL: process.env.NODE_ENV === 'production' ? '' : 'http://' //根据自己配置的反向代理去设置不同环境的baeUrl
baseURL: process.env.NODE_ENV === 'production' ? '' : 'http://' //根据自己配置的反向代理去设置不同环境的baeUrl
// baseURL: process.env.NODE_ENV === 'production' ? '' : 'http://' //根据自己配置的反向代理去设置不同环境的baeUrl
}
)
/**
* @param level 0: 无加密,1:参数加密,2: 签名 + 时间戳; 默认0
*/
// 请求拦截器
service.interceptors.request.use(
config => {
if (store.getters.token) {
const token = getToken()
//防串改需要,和后端配合使用
const level = 2
// 签名
let ts = timestamp()
// 签名key
let key = randomString(16);
let keyEncrypt = RSAencrypt(key);
// 随机字符串
let nonce = randomString(10);
let params = config.data
// 签名串
let signstr = sign(token, ts, params, key, nonce);
// let signstr = sign(token, ts , encrypt , key +"#"+iv , nonce);
config.headers = {
level: level,
ts: ts,
sign: signstr,
nonce: nonce,
token: token,
key: keyEncrypt
};
// config_.flag = key;
//默认配置token就行
// config.headers['token'] = token // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
}
return config
}, error => {
Message(error)
return Promise.reject(error)
}
)
// let httpCode = { //这里我简单列出一些常见的http状态码信息,可以自己去调整配置
// 400: '请求参数错误',
// 401: '权限不足, 请重新登录',
// 403: '服务器拒绝本次访问',
// 404: '请求资源未找到',
// 500: '内部服务器错误',
// 501: '服务器不支持该请求中使用的方法',
// 502: '网关错误',
// 504: '网关超时'
// }
// 响应拦截器
// response interceptor
service.interceptors.response.use(response => {
// loadingInstance.close()
if (response.data.code !=="200") {
_MessageBox
.confirm(response.data.msg, "提示", {
showCancelButton: false,
showConfirmButton: false,
type: "warning",
})
.then(() => { });
}
if (response.data.code) {
return Promise.resolve(response)
}
}, error => {
// loadingInstance.close()
console.log(error)
_MessageBox.confirm(error.response.data.data.message, '提示', {
showCancelButton: false,
showConfirmButton: false,
type: 'warning'
}).then(() => {
})
return Promise.reject(error)
const status = Number(error.toString().match(/\d{3}/)[0])
// console.log(status)
// if (status) {
// /**
// * 在这里:可以根据业务需求可以在请求失败后做什么。
// * 根据请求失败的http状态码去给用户相应的提示
// */
// let tips = status in httpCode ? httpCode[status] : error.response.data.message;
// // Message(tips)
// alert(tips)
// return Promise.reject(error)
// } else {
// Message("请求失败")
// return Promise.reject(new Error('请求失败'))
// }
})
/**
* 从1970年开始的毫秒数然后截取10位变成 从1970年开始的秒数
* @return 返回10位时间戳
*/
const timestamp = () => {
// new Date().getTime();
let tmp = Date.parse(new Date()).toString();
tmp = tmp.substr(0, 10);
return tmp;
}
/**
* 生成随机字符串
* @param len 指定长度
*/
const randomString = len => {
len = len || 32;
let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
let maxPos = $chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
/**
* get方法,对应get请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export function get(url, params) {
return new Promise((resolve, reject) => {
service({
method: 'get',
url,
params,
})
.then(res => {
resolve(res);
})
.catch(err => {
reject(err)
})
});
}
//传数组时
export function getOfQs(url, params) {
return new Promise((resolve, reject) => {
service({
method: 'get',
url,
params,
paramsSerializer: (params) => Qs.stringify(params, { indices: false }),
})
.then(res => {
resolve(res);
})
.catch(err => {
reject(err)
})
});
}
/**
* post方法,对应post请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
//传no和1时为表单状态,no为默认状态
export function post(url, params, dataType = 'J', from = '0') {
return new Promise((resolve, reject) => {
service({
method: 'post',
url,
data: dataType == 'no' ? params : (dataType == 'S' ? Qs.stringify(params) : Qs.parse(Qs.stringify(params))),
headers: {
'Content-Type': from == '1' ? 'multipart/form-data;boundary = ' + new Date().getTime() : 'application/json;charset=UTF-8',
},
})
.then(res => {
resolve(res);
})
.catch(err => {
reject(err)
})
});
}
export function delet(url, params) {
return new Promise((resolve, reject) => {
service({
method: 'delete',
url,
params,
})
.then(res => {
resolve(res)
})
.catch(err => {
reject(err)
})
})
}
export function put(url, params, dataType = 'J') {
return new Promise((resolve, reject) => {
service({
method: 'put',
url,
data: dataType == 'no' ? params : (dataType == 'S' ? Qs.stringify(params) : Qs.parse(Qs.stringify(params))),
})
.then(res => {
resolve(res);
})
.catch(err => {
reject(err)
})
});
}
export const view = (url, params) => {
// let token = getTokens()
// let queryParams = {docTemplate:'policy'}
// Object.assign(queryParams, params)
return axios({
method: 'get',
url: `${url}`,
params: params,
headers: {
'Content-Type': "application/json;charset=UTF-8"
},
responseType: "blob"
})
}
export const previewImg = (url, params) => {
// let token = getTokens()
// let queryParams = {docTemplate:'policy'}
// Object.assign(queryParams, params)
return axios({
method: 'get',
url: `${url}`,
params: params,
headers: {
'Content-Type': "application/json;charset=UTF-8"
},
responseType: "arraybuffer"//这是图片的返回类型
})
}
export default service
在api文件下引入创建xxx.js
使用的时候直接在页面引入api下的js,就行
import { post, get, getOfQs, delet, put } from '@/utils/http'
export const getCustomerList = data => post('api/customer/getCustomerList', data, "no","1")
二、使用步骤
1.引入crypto.js
代码如下(示例):
/**
* 通过crypto-js实现 加解密工具
* AES、HASH(MD5、SHA256)、base64
* @author: sgy
*/
//npm install crypto-js
import CryptoJS from 'crypto-js';
const KP = {
key: '1234567812345678', // 秘钥 16*n:
iv: '1234567812345678' // 偏移量
};
function getAesString(data, key, iv) { // 加密
key = CryptoJS.enc.Utf8.parse(key);
iv = CryptoJS.enc.Utf8.parse(iv);
let encrypted = CryptoJS.AES.encrypt(data, key,
{
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString(); // 返回的是base64格式的密文
}
function getDAesString(encrypted, key, iv) { // 解密
key = CryptoJS.enc.Utf8.parse(key);
iv = CryptoJS.enc.Utf8.parse(CryptoJS.enc.Base64.parse(iv).toString(CryptoJS.enc.Utf8));
let decrypted = CryptoJS.AES.decrypt(encrypted, key,
{
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// return {decrypt:decrypted.toString(CryptoJS.enc.Utf8),key:key,iv:iv};
return decrypted.toString(CryptoJS.enc.Utf8); //
}
// AES 对称秘钥加密
const aes = {
en: (data) => getAesString(data, KP.key, KP.iv),
de: (data) => getDAesString(data, KP.key, KP.iv)
};
const aesEn = (data,key,iv) => {
return getAesString(data, key, iv);
};
const aesDe = (data,key,iv) => {
return getDAesString(data, key, iv);
};
// BASE64
const base64 = {
// en: (data) => CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data)),
de: (data) => CryptoJS.enc.Base64.parse(data).toString(CryptoJS.enc.Utf8)
};
// SHA256
const sha256 = (data) => {
return CryptoJS.SHA256(data).toString();
};
// MD5
const md5 = (data) => {
return CryptoJS.MD5(data).toString();
};
/**
* 签名格式 data(字典升序)
*/
const dataSort = (data) => {
let ret = [];
for (let it in data) {
let val = data[it];
if (typeof val === 'object' && //
(!(val instanceof Array) || (val.length > 0 && (typeof val[0] === 'object')))) {
val = JSON.stringify(val);
}
ret.push(it + val);
}
// console.log("排序数据"+ ret);
// 字典升序
ret.sort();
return ret.join('');
};
/**
* 签名
* @param token 身份令牌
* @param timestamp 签名时间戳
* @param data 签名数据
* @param key 签名key
* @param nonce 随机字符串
*/
const sign = (token, timestamp, data , key , nonce) => {
// 签名格式 data(字典升序) + token + key(随机生成的秘钥) + ts(当前时间戳timestamp) + nonce(随机数)
let ret = [];
for (let it in data) {
let val = data[it];
if (typeof val === 'object' && //
(!(val instanceof Array) || (val.length > 0 && (typeof val[0] === 'object')))) {
val = JSON.stringify(val);
}
ret.push(it + val);
}
// 字典升序
ret.sort();
// console.log(ret);
let signsrc = ret.join('') + token + key + timestamp + nonce;
return md5(signsrc).toUpperCase();
};
export {
aes,
md5,
sha256,
base64,
sign,
dataSort,
aesEn,
aesDe
};
2.引入encrypt.js
import Vue from 'vue'
import JsEncrypt from 'jsencrypt'
Vue.prototype.$jsEncrypt = JsEncrypt
/**
* 接口安全
*
* 1. 安装
* jsencrypt是一个ras加密解密库
* npm install jsencrypt --save
*
* 2. main.js中引入
* import JsEncrypt from 'jsencrypt'
* Vue.prototype.$jsEncrypt = JsEncrypt
*/
let publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCDlvQQ9Lb5iO0Nw9tgMspQyv1FzVPOWkAhmcg3QiQGOKgXaCY4RGPTPVD4a54i6wkGQoOBM6JXPJmjzc44Xb31GBRHdLFTpkPVQbnIHxwKANPIxwfMgZgJSB5eNqBQKZYcKi2ZFrEHR6gFWH3sxpm+f3NPsKObwyyPQPqEMmHIiwIDAQAB'
let privateKey = 'MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAINPPCHa1AhnKGs+eE02JRSayReVCVVMTeOOjfbgY8DYATxkvDMqn6Xl+hHfs+ag3VI/A3BTyFL4z13iluvB01TPo5jLdaCKBXxeT2PGr6RiuMAdh1+ZeDaORiyngX+9x2pATvOobO2ITHX4Kw0LyuqicPTrvWxUUQnLoHb5ZMYTAgMBAAECgYA3Iof/NyEcviPsk/hzgy6irjONoVif5kA2Ml9Nr/5ytMAgGbQkT9tlD2GnK6UgS59ir27ENYnBvRNlOoVgTKxtLPUo2rrsTWQRjPnwkrNW6VemAyly0OEpFMvjr16TfcDo+BM1jzy4h9YCj0SwqA7dcPZu1wwvWsRBcM0eZpykMQJBAOCOhoj2VqTrbME2u3HibEz2mULrIzt+FO6fhZWJp06Voc5XhSKsLhlom8Du/VyBHaBi/r8yIcgmyGMwb1CRbt8CQQCVsinfLjGvg1f2cnRNi83R3CG60VGmOXKr+kz8n+fMwqSCANTG49J/x35AxJL/ufsnC2CRZdCh03mk4iEdcDNNAkBmLPPSRiROjkDB+aF4xEn7CwnZhRxW6ZukqDkkPao++57QQMp3aFjhftPACf6GpMlSPTkkzi7I37y2RUehJUuJAkBtM+CJ2EgUsqs7tLkVTPSjsIPGpiZ7LZNy1BDPhdNys1eRIwwV32LTJnP6yaw287S9Afa7etvdAcnOt8vSjuRNAkAmQCWevpugflLchIswjxb03gJY4HZY88GN2KmCKJ0WVVTJv/9o5guTI4WY50m1tMt/PcoVO6cNvRWn9+JlXYDw'
//加密方法
export function RSAencrypt(pas) {
//实例化jsEncrypt对象
let jse = new JSEncrypt();
//设置公钥
jse.setPublicKey(publicKey);
return jse.encrypt(pas);
}
//解密方法
export function RSAdecrypt(pas) {
let jse = new JSEncrypt();
// 私钥
jse.setPrivateKey(privateKey)
// console.log('解密:'+jse.decrypt(pas))
return jse.decrypt(pas);
}