You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一用户触发多次verifyOtp重复请求问题排查求助

同一用户触发多次verifyOtp重复请求问题排查求助

大家好,我现在遇到一个棘手的问题:用户提交verifyPINForm表单时,verifyOtp接口请求偶尔会同时发送两次,导致后端出现业务逻辑冲突。想请各位帮忙排查可能的原因,以及有没有遗漏的解决思路。

问题描述

用户输入6位PIN码后点击提交按钮,正常情况下只会触发一次verifyOtp请求,但偶尔会出现两次请求同时发出的情况,后端因为重复请求触发了业务异常(比如优惠码重复使用的报错)。

相关代码

组件模板(HTML)

<form [formGroup]="verifyPINForm" novalidate (ngSubmit)="submitForm()">
  <div class="enter-verification-code">
    <p>{{ "VERIFICATION_CODE_TITLE" | translate }}</p>
    <input 
      inputmode="numeric" 
      [ngClass]="{ 'invalid-field': verifyPINForm.invalid && isFormSubmitted }" 
      type="text" 
      formControlName="pin" 
      maxlength="6" 
      placeholder="{{ 'OTP_PLACE_HOLDER' | translate }}" 
    />
    <div class="error-text-container" *ngIf="(pinControl.invalid && pinControl.touched) && pinControl.dirty">
      <small *ngIf="pinControl.errors?.required" class="text-danger">
        {{ "VALIDATION.PIN_REQUIRED" | translate}}
      </small>
    </div>
  </div>
  <button 
    type="button" 
    (click)="closeDialog()" 
    *ngIf="!!errorMessage || statusCode == sendOtpErrors.discount_code_used_error || statusCode == sendOtpErrors.discount_code_used_same_time_error || statusCode == sendOtpErrors.discount_code_not_active || statusCode == sendOtpErrors.already_sent_otp"
  >
    {{ "TRY_AGAIN" | translate}}
  </button>
  <button 
    *ngIf="!errorMessage && statusCode != sendOtpErrors.discount_code_used_error && statusCode != sendOtpErrors.discount_code_used_same_time_error && statusCode != sendOtpErrors.discount_code_not_active && statusCode != sendOtpErrors.already_sent_otp"
    [disabled]="submissionInProgress || isDisabledSendBtn || isFormSubmitted || utilService.isLoading || verifyPINForm.invalid" 
    type="submit"
  >
    {{ "CONFIRM_PAYMENT_ACTION" | translate}}
  </button>
</form>

组件逻辑(TS)

// 核心提交方法
submitForm(): void {
  if (this.shouldPreventSubmission()) {
    this.utilService.logMessage("Submission prevented - already processing", null);
    return;
  }
  // 立即标记提交中状态,试图拦截后续请求
  this.prepareForSubmission();
  // 生成唯一请求ID追踪当前请求
  const requestId = this.generateRequestId();
  this.currentRequestId = requestId;

  // 延迟处理请求,确保UI状态更新完成
  setTimeout(() => {
    if (this.currentRequestId === requestId) {
      this.processVerifyOtp(requestId);
    } else {
      this.utilService.logMessage("Request already superseded by newer request", null);
    }
  }, 50);
}

// 处理OTP验证请求
private processVerifyOtp(requestId: string): void {
  if (requestId !== this.currentRequestId) {
    return;
  }
  const payload: VerifyTransactionOtpRequest = {
    transactionOTP: this.pinControl.value,
    transactionId: this.state.transactionID
  };
  this.utilService.logMessage("Verify Otp payload: ", payload);
  this.utilService.showLoading();
  
  this.transactionService.verifyOtp(payload)
    .pipe(
      finalize(() => {
        if (requestId === this.currentRequestId) {
          this.utilService.hideLoading();
          this.currentRequestId = null;
          this.handleSubmissionComplete();
        }
      })
    )
    .subscribe({
      next: (response: any) => {
        if (requestId === this.currentRequestId) {
          this.handleVerifyOtpResponse(response);
        }
      },
      error: (error) => {
        if (requestId === this.currentRequestId) {
          this.handleVerifyOtpError(error);
        }
      }
    });
}

服务层请求方法

public verifyOtp(payload: VerifyTransactionOtpRequest) {
  return this._http.post<VerifyTransactionOtpResponse>(ApiEndpointsMapper.payment.transaction.commit.verifyOtp, payload)
}

已尝试的解决措施

  1. UI层面拦截:给提交按钮绑定[disabled]属性,关联submissionInProgress、表单验证状态等,试图阻止重复点击
  2. 请求ID追踪:用唯一ID标记当前活跃请求,后续请求会被拦截
  3. 延迟处理请求:加入setTimeout确保UI状态更新完成后再发请求
  4. 状态标记拦截:之前版本直接通过isDisabledSendBtn标记禁用按钮,同样无效

疑问与求助

  1. 这种重复请求是否和用户的网络状况有关?比如网络波动导致前端没及时收到响应,从而触发重复提交?
  2. 有没有可能是表单提交事件被多次触发?比如ngSubmit和按钮的默认行为存在冲突?
  3. 我当前的防重复提交逻辑是否存在漏洞?比如submissionInProgress的设置时机是否不够早?
  4. 除了前端逻辑,还有没有其他可能的原因导致重复请求?

麻烦各位帮忙看看,有没有我忽略的点,或者其他排查方向?谢谢大家!

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 06:18:44