vue-resource请求限流实现:防止重复提交与频率控制

vue-resource请求限流实现:防止重复提交与频率控制

【免费下载链接】vue-resource The HTTP client for Vue.js 【免费下载链接】vue-resource 项目地址: https://gitcode.com/gh_mirrors/vue/vue-resource

在Web应用开发中,用户频繁点击按钮导致重复提交、API请求频率过高引发服务器过载等问题屡见不鲜。vue-resource作为Vue.js生态中经典的HTTP客户端,虽然未直接提供限流功能,但通过其灵活的拦截器机制,我们可以轻松实现请求限流策略。本文将详解如何基于src/http/interceptor/拦截器系统,构建双重防护机制:请求防抖(防止重复提交)和频率控制(限制单位时间内请求次数)。

拦截器基础:vue-resource的请求拦截链

vue-resource的拦截器系统是实现限流的核心基础。在请求发送前,框架会依次执行src/http/interceptor/before.jssrc/http/interceptor/method.js等拦截器。其中,before拦截器(如代码1所示)允许在请求发送前执行自定义逻辑,这为我们注入限流检查提供了最佳切入点。

代码1:before拦截器基础结构

// src/http/interceptor/before.js
import {isFunction} from '../../util';

export default function (request) {
    if (isFunction(request.before)) {
        request.before.call(this, request);
    }
}

方案设计:双重防护的限流架构

我们将通过以下两个层级实现限流:

mermaid

  • 请求防抖层:通过记录未完成请求的唯一标识(如URL+方法),阻止用户在短时间内重复提交同一请求。
  • 频率控制层:维护请求时间戳队列,确保单位时间内的请求次数不超过预设阈值。

实现步骤1:请求防抖拦截器

首先扩展before拦截器,添加请求唯一标识的检查逻辑。我们需要修改src/http/interceptor/before.js,引入一个全局请求状态跟踪对象:

代码2:防重复提交拦截器实现

// src/http/interceptor/before.js
import {isFunction} from '../../util';

// 跟踪进行中的请求
const pendingRequests = new Map();

export default function (request) {
    // 生成请求唯一标识(URL+方法)
    const requestKey = `${request.url}-${request.method}`;
    
    // 检查是否存在未完成请求
    if (pendingRequests.has(requestKey)) {
        // 取消当前请求
        request.abort();
        console.warn(`重复请求已拦截: ${requestKey}`);
        return;
    }
    
    // 标记请求为进行中
    pendingRequests.set(requestKey, true);
    
    // 请求完成/失败后移除标记
    request.then(() => {
        pendingRequests.delete(requestKey);
    }).catch(() => {
        pendingRequests.delete(requestKey);
    });

    if (isFunction(request.before)) {
        request.before.call(this, request);
    }
}

实现步骤2:频率控制中间件

接下来实现频率控制逻辑,通过时间戳队列控制单位时间内的请求总量。在src/http/interceptor/目录下创建rate-limit.js

代码3:频率控制拦截器

// src/http/interceptor/rate-limit.js
const requestTimestamps = [];
const RATE_LIMIT = 10; // 单位时间内最大请求数
const RATE_WINDOW = 1000; // 时间窗口(毫秒)

export default function (request) {
    const now = Date.now();
    
    // 清除过期的时间戳
    requestTimestamps.filter(timestamp => now - timestamp < RATE_WINDOW);
    
    if (requestTimestamps.length >= RATE_LIMIT) {
        request.abort();
        console.warn(`请求频率超限,请稍后再试`);
        return;
    }
    
    // 记录当前请求时间戳
    requestTimestamps.push(now);
}

实现步骤3:注册拦截器

最后需要在src/http/index.js中注册新的拦截器,确保限流逻辑在请求发送前执行:

代码4:注册限流拦截器

// src/http/index.js
import before from './interceptor/before';
import rateLimit from './interceptor/rate-limit'; // 导入新拦截器

// 添加到拦截器队列
const interceptors = [
    before,
    rateLimit, // 限流拦截器
    method,
    // ...其他拦截器
];

配置与使用

在实际项目中,可通过Vue全局配置自定义限流参数:

Vue.http.options.rateLimit = {
    maxRequests: 10,    // 最大请求数
    timeWindow: 1000    // 时间窗口(毫秒)
};

对于不需要限流的特殊请求(如文件上传),可通过请求配置跳过检查:

this.$http.get('/api/large-file', {
    skipRateLimit: true  // 跳过限流检查
});

测试与验证

可通过test/http.test.js添加限流场景测试用例:

// 测试重复请求拦截
it('should block duplicate requests', (done) => {
    const firstRequest = Vue.http.get('/api/test');
    const secondRequest = Vue.http.get('/api/test');
    
    secondRequest.catch(error => {
        expect(error.message).to.include('重复请求已拦截');
        done();
    });
});

总结与扩展

通过扩展vue-resource的拦截器系统,我们实现了无侵入式的请求限流方案。该方案具有以下优势:

  1. 低耦合:基于拦截器机制,无需修改核心源码。
  2. 可配置:支持全局参数与请求级别的例外处理。
  3. 高性能:基于Map和数组实现状态跟踪,时间复杂度为O(1)。

后续可进一步优化,如添加动态限流阈值调整、用户级别的频率控制等功能。完整实现请参考src/http/interceptor/目录下的拦截器代码。

【免费下载链接】vue-resource The HTTP client for Vue.js 【免费下载链接】vue-resource 项目地址: https://gitcode.com/gh_mirrors/vue/vue-resource

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值