From 8ec31d9c3fb9973306be1c55a4a758401874ed68 Mon Sep 17 00:00:00 2001 From: qq_15911201 Date: Tue, 27 Feb 2024 21:26:00 +0800 Subject: [PATCH] Tue Feb 27 21:26:00 CST 2024 inscode --- src/components/HelloWorld.vue | 75 +++++++--------- "src/\346\216\245\345\217\243/axios.js" | 86 +++++++++++++++++++ .../global.config.js" | 10 +++ "src/\346\216\245\345\217\243/login.js" | 21 +++++ "src/\346\216\245\345\217\243/request.js" | 34 ++++++++ 5 files changed, 184 insertions(+), 42 deletions(-) create mode 100644 "src/\346\216\245\345\217\243/axios.js" create mode 100644 "src/\346\216\245\345\217\243/global.config.js" create mode 100644 "src/\346\216\245\345\217\243/login.js" create mode 100644 "src/\346\216\245\345\217\243/request.js" diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue index 1b8faac..f0eba9f 100644 --- a/src/components/HelloWorld.vue +++ b/src/components/HelloWorld.vue @@ -1,43 +1,34 @@ - +import request from '../axios'// 引入封装好的axios请求对象 +//节流 +// 创建一个立即执行函数,利用闭包来保存已经请求过的接口地址 +let myRequest = (function () { + //通过这种闭包的写法,这个hasRequest 就不会被内存回收 + let hasRequest = [] //这样可以利用缓存来记录我们请求了哪些接口 + //一但有请求就会记录这个数组里面 + return function (config) { + let url = config.url + //每次发请求之前先判断一下,这个数组里面是不是已经存在本次要请求的url了 + if (hasRequest.indexOf(url) !== -1) {//传过来的配置文件里是不是已经存在了这个数组里面 + //判断一下数组里面是不是已经请求了这个地址,如果这个判断不等-1就说明存在了 + return Promise.reject({ meg: '请求已提交' }) + } + //如果不存的话,然后发送请求,请求之前先把这个地址存到这个数组里 + hasRequest.push(url) + return request({ //然后使用request去发送请求,然后吧config直接在这个里面展开 + ...config + }).then((res) => {//请求成功后,我们把这个url从这个数组里删掉 + hasRequest = hasRequest.filter((item => { + if (item !== url) {//使用filter进行删除,如果不等于请求成功的这个地址就可以不用删除 + return item + } + })) + return res + }) + } +})() - - - +// 将myRequest导出为request,并将原始的request对象导出为initRequest +export { + myRequest as request,// 使用myRequest作为默认的request请求函数 + request as initRequest// 将原始的request对象导出为initRequest +} \ No newline at end of file diff --git "a/src/\346\216\245\345\217\243/axios.js" "b/src/\346\216\245\345\217\243/axios.js" new file mode 100644 index 0000000..33b7b8d --- /dev/null +++ "b/src/\346\216\245\345\217\243/axios.js" @@ -0,0 +1,86 @@ +// 配置全局的基础配置 +import axios from 'axios' //导入axios库,用于发送HTTP请求 + +//配置中心 +import WEBconfig from './global.config' + +// 导入 vue-router 库,用于路由跳转 +import { useRouter } from 'vue-router' +let router = useRouter() + +import md5 from 'js-md5' + +//通过axios.create去创建一个axios的对象,使用来对项目发请求的一个对象。 +//后面的请求通过使用request来发送请求 +let request = axios.create({ + //1、配置 + baseURL: 'http://localhost:3000/',// 基础 URL 地址 + timeout: 30 * 1000,//设置超时时间为30秒 +}) + +// 请求拦截器,在请求发送前进行处理 +//config包含的这我们发送请求的一些头部、参数等。 +request.interceptors.request.use((config) => { + //token + let whiteLis = WEBconfig.whiteListApi// 获取白名单列表 + let url = config.url // 获取请求的 URL + let token = localStorage.getItem('token') + // @ts-ignore + // 如果请求的 URL 不在白名单中且存在 token,则将 token 添加到请求头中 + if (!whiteLis.indexOf(url) && token) { + config.headers.token = token + } + //密钥 - secretId+特殊的算法 = 密钥- + // @ts-ignore + let secret = md5(WEBconfig.secretId + new Date().toString()) + config.headers.secret = secret + return config +}, error => { + // 请求拦截器发生错误时的处理 + console.error('Request interceptor error:', error) + // 返回一个带有拒绝状态的 Promise 对象 + return Promise.reject(error) +}) + +// 响应拦截器,在收到响应后进行处理 +request.interceptors.request.use((res) => { + //响应统一处理 + const { data } = res + const status = data?.code || 200// 获取响应状态码,默认为 200 + const message = data?.msg || '未知错误'// 获取响应消息,默认为 '未知错误' + // 如果状态码为 401,则表示权限错误,跳转到登录页面 + if (status === 401) { + // 处理权限错误,跳转到登录页面 + alert('你没有权限') + router.push('/login') + // 返回一个带有拒绝状态的 Promise 对象,并附带错误信息 + return Promise.reject(new Error(message)) + } else if (status !== 200) { + // 其他错误情况的处理 + alert(`错误码:${status},错误信息:${message}`) + return Promise.reject(new Error(message)) + } + return res +}, error => {//相应失败的拦截 + console.error('Response interceptor error:', error) + alert('响应失败,请稍后重试') + return Promise.reject(new Error(error)) +}) + +// 导出自定义配置的 axios 实例 +export default request; + +/** + * 在这个文件中去要做的事情: + * 1、基本全局配置 + * 如 baseURL,超时时间等 + * 2、Token,密钥等 + * 处于权限和安全考虑的密钥设置到请求头 + * 3、相应的统一基本处理 + * 主要针对于错误的情况做全局统一处理 + * + * baseURL:请求的基本URL + * timeout:请求的超时时间 + * responseType:指定服务器响应的数据类型 + * withCredentials:用于指定是否应该在跨域请求中发送凭证。 +*/ \ No newline at end of file diff --git "a/src/\346\216\245\345\217\243/global.config.js" "b/src/\346\216\245\345\217\243/global.config.js" new file mode 100644 index 0000000..dbaab52 --- /dev/null +++ "b/src/\346\216\245\345\217\243/global.config.js" @@ -0,0 +1,10 @@ +export default { + // 对象属性:白名单 API 数组,用于存储允许访问的 API 路径 + whiteListApi: ["/login"], + // 对象属性:秘密 ID 字符串,用于身份验证或其他安全相关的操作 + secretId: 'helloworld' +} + + + + diff --git "a/src/\346\216\245\345\217\243/login.js" "b/src/\346\216\245\345\217\243/login.js" new file mode 100644 index 0000000..392b4f9 --- /dev/null +++ "b/src/\346\216\245\345\217\243/login.js" @@ -0,0 +1,21 @@ +// 导入 './request' 模块中的 'request' 函数 +import { request } from './request' +// 定义一个名为 'LoginAPI' 的函数,使用箭头函数语法 +export const LoginAPI = () => { + // 在 'LoginAPI' 函数内部,返回一个对象 + return { + // 在返回的对象内部,使用箭头函数语法定义一个名为 'login' 的方法 + login: (data) => { + // 在 'login' 方法内部,调用 'request' 函数 + // 将包含 method、url 和 data 属性的对象作为参数传递给 'request' 函数 + return request({ + // 将 HTTP 方法指定为 'post' + method: "post", + // 将端点 URL 指定为 '/userLogin' + url: "/userLogin", + // 将 'data' 参数传递以随请求发送 + data + }) + } + } +} \ No newline at end of file diff --git "a/src/\346\216\245\345\217\243/request.js" "b/src/\346\216\245\345\217\243/request.js" new file mode 100644 index 0000000..c869d8a --- /dev/null +++ "b/src/\346\216\245\345\217\243/request.js" @@ -0,0 +1,34 @@ +import request from '../axios'// 引入封装好的axios请求对象 +//节流 +// 创建一个立即执行函数,利用闭包来保存已经请求过的接口地址 +let myRequest = (function () { + //通过这种闭包的写法,这个hasRequest 就不会被内存回收 + let hasRequest = [] //这样可以利用缓存来记录我们请求了哪些接口 + //一但有请求就会记录这个数组里面 + return function (config) { + let url = config.url + //每次发请求之前先判断一下,这个数组里面是不是已经存在本次要请求的url了 + if (hasRequest.indexOf(url) !== -1) {//传过来的配置文件里是不是已经存在了这个数组里面 + //判断一下数组里面是不是已经请求了这个地址,如果这个判断不等-1就说明存在了 + return Promise.reject({ meg: '请求已提交' }) + } + //如果不存的话,然后发送请求,请求之前先把这个地址存到这个数组里 + hasRequest.push(url) + return request({ //然后使用request去发送请求,然后吧config直接在这个里面展开 + ...config + }).then((res) => {//请求成功后,我们把这个url从这个数组里删掉 + hasRequest = hasRequest.filter((item => { + if (item !== url) {//使用filter进行删除,如果不等于请求成功的这个地址就可以不用删除 + return item + } + })) + return res + }) + } +})() + +// 将myRequest导出为request,并将原始的request对象导出为initRequest +export { + myRequest as request,// 使用myRequest作为默认的request请求函数 + request as initRequest// 将原始的request对象导出为initRequest +} \ No newline at end of file -- GitLab