uniapp prevents duplicate submission of data

When the user taps the button quickly. We can uniformly do the processing to prevent repeated submission of data in the request interceptor

The following is the request request packaged with uview2

import { autoLogin, getUserInfo } from '@/utils/method.js'
import { refreshToken } from '@/api/login.js'
const serversUrl = require('./serversUrl.js').serversUrl

// 白名单
const whiteList = [
	'/szg-admin/api/app/wxLogin',
	'/szg-admin/api/app/bingMobile',
	'/auth/client/sms/sendCode',
	'/auth/client/smsCode/login'
]

module.exports = (vm) => {
	// 初始化请求配置
	uni.$u.http.setConfig((defaultConfig) => {
		// #ifdef H5
		defaultConfig.baseURL = '/h5api'
		// #endif

		// #ifndef H5
		defaultConfig.baseURL = serversUrl
		defaultConfig.sslVerify = false
		defaultConfig.firstIpv4 = false
		// #endif

		// 要加上这个 Content-type,不然app端请求会得不到响应
		defaultConfig.header['Content-Type'] = 'application/json;charset=UTF-8'
		defaultConfig.timeout = 20000
		return defaultConfig
	})

	// 请求拦截
	uni.$u.http.interceptors.request.use((config) => {
		// 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
		config.data = config.data || {}

		// 防止数据重复提交
		if (config.method === 'POST' || config.method === 'PUT' || config.method === 'DELETE') {
			const requestObj = {
				url: config.url,
				data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
				time: new Date().getTime()
			}

			const storageRequestObj = uni.getStorageSync('storageRequestObj')
			if (!storageRequestObj) {
				uni.setStorageSync('storageRequestObj', requestObj)
			} else {
				const s_url = storageRequestObj.url
				const s_data = storageRequestObj.data
				const s_time = storageRequestObj.time
				// 间隔时间(ms),小于此时间视为重复提交
				const interval = 1000
				if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
					return Promise.reject('数据正在处理,请勿重复提交')
				} else {
					uni.setStorageSync('storageRequestObj', requestObj)
				}
			}
		}

		if (whiteList.includes(config.url)) return config

		const token = uni.getStorageSync('token')
		if (token) {
			config.header.Authorization = `Bearer ${ token }`
		}

		return config
	}, err => {
		// 可使用async await 做异步操作
		return Promise.reject(err)
	})

	// 响应拦截
	uni.$u.http.interceptors.response.use((response) => {
		// console.log('响应拦截==', response);
		if (response.statusCode === 200 && response.data.code == 401) {
			uni.showModal({
				title: '页面停留超时',
				content: '请重新进入后继续操作',
				confirmText: '重新进入',
				showCancel: false,
				success: async e => {
					uni.removeStorageSync('token')

					// #ifdef MP-WEIXIN
					await autoLogin()
					// #endif

					// #ifndef MP-WEIXIN
					// 如果当前就在登录页面,不进行跳转
					if (uni.$u.page() != '/pages/login') {
						uni.navigateTo({ url: '/pages/login' })
					}
					// #endif

					return Promise.reject(response.data.msg || '页面停留超时')
				}
			})
		} else if (response.statusCode === 200) {
			return response.data
		} else {
			uni.showModal({
				title: '温馨提示',
				content: response.data.msg || response.data.error,
				showCancel: false
			})
			return Promise.reject(response.data.msg)
		}
	}, (err) => {
		// 对响应错误做点什么 statusCode !== 200
		console.log('<<<<<<响应错误>>>>>>', err)
		return Promise.reject(err)
	})
}

You just need to pay attention to this piece of code. You can directly copy this piece of code and put it in your project

// 防止数据重复提交
if (config.method === 'POST' || config.method === 'PUT' || config.method === 'DELETE') {
    const requestObj = {
        url: config.url,
        data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
        time: new Date().getTime()
    }

    const storageRequestObj = uni.getStorageSync('storageRequestObj')
    if (!storageRequestObj) {
        uni.setStorageSync('storageRequestObj', requestObj)
    } else {
        const s_url = storageRequestObj.url
        const s_data = storageRequestObj.data
        const s_time = storageRequestObj.time
        // 间隔时间(ms),小于此时间视为重复提交
        const interval = 1000
        if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
            return Promise.reject('数据正在处理,请勿重复提交')
        } else {
            uni.setStorageSync('storageRequestObj', requestObj)
        }
    }
}

Currently, throttling ( triggered only once within a specified time ) can also be done on the button .

Note: This article is based on the uview2 framework

<template>
    <view class="">
		<!-- 此处用法为在模板中使用,无需写this,直接$u.throttle()即可 -->
    	<view @click="$u.throttle(btnAClick, 500)">
    		露从今夜白
    	</view>
        
        <!-- 在模板中传参写法 -->
    	<view @click="$u.throttle(() => { onBuy(1) }, 1000)">
    		购买
    	</view>

    	<view @click="onCollect(1)">
    		收藏
    	</view>
    </view>
</template>

<script>
    export default {
        methods: {
            btnAClick() {
				console.log('btnClick');
			},

			onBuy(num) {
                console.log('购买', num);
			},

            onCollect(num) {
                // 此处用法为在js中调用,需要写uni.$u.throttle()
                uni.$u.throttle(() => {
					console.log('收藏', num);
				}, 1000)
            }
        }
    }
</script>

Guess you like

Origin blog.csdn.net/qq_23375733/article/details/131669488