同一用户触发多次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) }
已尝试的解决措施
- UI层面拦截:给提交按钮绑定
[disabled]属性,关联submissionInProgress、表单验证状态等,试图阻止重复点击 - 请求ID追踪:用唯一ID标记当前活跃请求,后续请求会被拦截
- 延迟处理请求:加入
setTimeout确保UI状态更新完成后再发请求 - 状态标记拦截:之前版本直接通过
isDisabledSendBtn标记禁用按钮,同样无效
疑问与求助
- 这种重复请求是否和用户的网络状况有关?比如网络波动导致前端没及时收到响应,从而触发重复提交?
- 有没有可能是表单提交事件被多次触发?比如
ngSubmit和按钮的默认行为存在冲突? - 我当前的防重复提交逻辑是否存在漏洞?比如
submissionInProgress的设置时机是否不够早? - 除了前端逻辑,还有没有其他可能的原因导致重复请求?
麻烦各位帮忙看看,有没有我忽略的点,或者其他排查方向?谢谢大家!
相关产品推荐
相关产品推荐

