axios拦截器只弹一次el-message实现方法

3 篇文章 0 订阅

场景说明

同一个账号,两个人使用,第二个人登录成功后,当第一个人再次操作界面时,所有接口返回特定的102码,这时前端知道这个账号异地登录了,现在要做的是让前端给第一个人一个提示,告诉他他的账号被别人使用了。

错误尝试

第一反应是在axios拦截器内实现message弹出操作,实际情况是,第一个人触发102码的时候并不是每次只有一个接口请求,可能会有好几个axios同时请求得到102码,这个时候就会出现下面的场景:

在这里插入图片描述

错误代码(简写)

import axios from 'axios'
import {Message} from 'element-ui'
const http = axios.create({
	timeout: 1000 * 60 * 2,
	withCredentials: true
})
// 当为post请求时设置其Content-Type为application/x-www-form-urlencoded
http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// 响应拦截
http.interceptors.response.use(res => {
	if (res.data.code === 102) {
		Message({
			message: '当前账号已经在其他客户端登录',
			type: 'warning',
		})
		// 这里执行清除token和跳转到登录页等操作)

解决办法

如何解决弹窗多次弹出的问题呢?实际情况下我们只希望它弹一次!

新建一个messageOnce.js文件,如下:

import {Message} from 'element-ui'
// 私有属性,只在当前文件可用
const showMessage = Symbol('showMessage')
export default class domMessage {
	success (options, single = true) {
		this[showMessage]('success', options, single)
	}
	warning(options, single = true) {
		this[showMessage]('warning', options, single)
	}
	info(options, single = true) {
		this[showMessage]('info', options, single)
	}
	error(options, single = true) {
		this[showMessage]('error', options, single)
	}
	[showMessage] (type, options, single) {
		if (single) {
			// 关键代码,判断当前页是否有el-message标签,如果没有则执行弹窗操作
			if (document.getElementsByClassName('el-message').length === 0) {
				Message[type](options)
			}
		} else {
			Message[type](options)
		}
	}
}

在处理响应拦截的文件中引入messageOnce.js,如下:

import axios from 'axios'
import domMessage from './messageOnce'

// new 对象实例
const messageOnce = new domMessage()
const http = axios.create({
	timeout: 1000 * 60 * 2,
	withCredentials: true
})
// 当为post请求时设置其Content-Type为application/x-www-form-urlencoded
http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// 响应拦截
http.interceptors.response.use(res => {
	if (res.data.code === 102) {
		messageOnce.warning({
			message: '当前账号已经在其他客户端登录',
			type: 'warning'
		})
		// 这里执行清除token和跳转到登录页等操作)

总结

一开始打算使用防抖函数来处理,发现没法解决这个问题,后来向朋友请教,提供了这个思路给我,很受用。如果觉得文章不错,点个赞再走吧!

1. 首先安装axioselement-ui: ``` npm install axios element-ui --save ``` 2. 在需要使用el-upload组件的页面中,引入axioselement-ui: ```javascript import axios from 'axios' import { Upload, MessageBox } from 'element-ui' ``` 3. 在template中使用el-upload组件: ```html <el-upload class="upload-demo" action="/api/upload" :on-change="handleUpload" :before-upload="beforeUpload" :headers="headers" :data="uploadData" :auto-upload="false" :file-list="fileList" :on-remove="handleRemove" :on-success="handleSuccess" :on-error="handleError" > <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="upload">上传文件</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> </el-upload> ``` 其中,action属性指定了上传文件的api地址;before-upload属性指定了上传文件前的校验函数;headers属性和data属性分别指定了请求的header和请求的参数;auto-upload属性设置为false,表示不自动上传文件;file-list属性绑定了已上传的文件列表;on-remove、on-success和on-error分别指定了文件移除、上传成功和上传失败的回调函数。 4. 在methods中添加上传文件的相关函数: ```javascript methods: { beforeUpload(file) { const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'; const isLt500k = file.size / 1024 < 500; if (!isJPG) { this.$message.error('上传头像图片只能是 JPG/PNG 格式!'); } if (!isLt500k) { this.$message.error('上传头像图片大小不能超过 500KB!'); } return isJPG && isLt500k; }, handleUpload() { // 当上传文件列表发生变化时调用 }, upload() { this.$refs.upload.submit(); }, handleRemove(file, fileList) { // 当文件列表中的某个文件被移除时调用 }, handleSuccess(res, file, fileList) { // 当文件上传成功时调用 }, handleError(err, file, fileList) { // 当文件上传失败时调用 } } ``` 5. 在handleSuccess函数中发起axios请求: ```javascript handleSuccess(res, file, fileList) { if (res.code === 0) { this.$message.success('上传成功'); // 上传成功后,将文件信息添加到fileList中 const { id, name, url } = res.data; fileList[fileList.length - 1].id = id; fileList[fileList.length - 1].name = name; fileList[fileList.length - 1].url = url; } else { this.$message.error('上传失败'); } }, ``` 在这个函数中,我们判断了上传结果的code,如果为0则表示上传成功,将文件信息添加到fileList中;否则表示上传失败,弹出提示信息。 6. 在created生命周期函数中设置请求header: ```javascript created() { this.headers = { Authorization: `Bearer ${localStorage.getItem('token')}` }; } ``` 在这里,我们将请求header设置为包含Authorization字段的对象,其值为从localStorage中获取的token。 7. 在methods中定义上传文件的函数: ```javascript upload() { this.$refs.upload.submit(); } ``` 该函数调用了el-upload组件的submit方法,用于上传文件。 8. 最后,在methods中定义handleUpload函数: ```javascript handleUpload() { // 获取上传文件列表 const files = this.$refs.upload.uploadFiles; // 遍历上传文件列表,发起axios请求 files.forEach(file => { const formData = new FormData(); formData.append('file', file.raw); axios.post('/api/upload', formData, { headers: { 'Content-Type': 'multipart/form-data', Authorization: `Bearer ${localStorage.getItem('token')}` }, onUploadProgress: (progressEvent) => { // 显示上传进度条 const percent = Math.floor((progressEvent.loaded / progressEvent.total) * 100); this.$set(file, 'percentage', percent); } }).then(res => { if (res.code === 0) { this.$message.success('上传成功'); // 上传成功后,将文件信息添加到fileList中 const { id, name, url } = res.data; this.fileList.push({ id, name, url }); } else { this.$message.error('上传失败'); } }).catch(err => { this.$message.error('上传失败'); }); }); } ``` 在这个函数中,我们获取上传文件列表,遍历上传文件列表,发起axios请求,将文件信息添加到fileList中。同时,我们通过设置onUploadProgress回调函数,实时更新上传进度条。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值