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

如何为重试函数设置过期时间?验证码重获功能实现

Got it, let's break this down into two clear parts: handling the expired captcha prompt with a retry option, and setting expiration limits for retry functions. Here's how you can tackle both effectively:

1. Implementing "Expired, Retry" for Captcha Collection

First, you need to track the captcha's expiration from the moment it's generated, then build logic to trigger the retry prompt when it's no longer valid. Here's a step-by-step approach:

  • Store expiration data with the captcha: When your backend generates a captcha, save not just the captcha value but also an expiration timestamp (e.g., current time + 120 seconds for 2-minute validity). Use a cache like Redis (for production) or a session store, linked to a unique user/session ID.
  • Frontend prompt: proactive or reactive:
    • Proactive: Start a 2-minute timer as soon as the captcha loads. When it hits zero, hide the captcha and show a "Captcha expired, click to re-obtain" message that's clickable.
    • Reactive: If the user tries to submit an expired captcha, your backend returns an error like {"error": "captcha_expired"}—the frontend then switches to the retry prompt.
  • Refresh on retry: When the user clicks the retry button, send a request to your captcha generation endpoint again. Clear the old captcha data from storage, generate a new one with a fresh expiration, and render it to the user.

Example Code Snippets

Backend (Python/Flask):

import time
from flask import Flask, request, jsonify

app = Flask(__name__)
# Use Redis in production instead of this in-memory dict
captcha_storage = {}

@app.route('/generate-captcha')
def generate_captcha():
    session_id = request.args.get('session_id')
    captcha_value = "XYZ123"  # Replace with your actual captcha generator
    expiration_time = int(time.time()) + 120  # 2 minutes from now
    captcha_storage[session_id] = {"value": captcha_value, "expires": expiration_time}
    return jsonify({"captcha": captcha_value, "expires_at": expiration_time})

@app.route('/verify-captcha', methods=['POST'])
def verify_captcha():
    data = request.get_json()
    session_id = data['session_id']
    submitted_captcha = data['captcha']

    if session_id not in captcha_storage:
        return jsonify({"error": "captcha_not_found"}), 400

    captcha_data = captcha_storage[session_id]
    if int(time.time()) > captcha_data['expires']:
        del captcha_storage[session_id]  # Clean up expired data
        return jsonify({"error": "captcha_expired"}), 400

    if submitted_captcha == captcha_data['value']:
        del captcha_storage[session_id]
        return jsonify({"success": True})
    else:
        return jsonify({"error": "invalid_captcha"}), 400

Frontend (JavaScript):

let captchaTimer;
const sessionId = "user-session-123"; // Get this from your session system

function fetchNewCaptcha() {
    // Clear existing timer to avoid duplicate prompts
    if (captchaTimer) clearTimeout(captchaTimer);

    fetch(`/generate-captcha?session_id=${sessionId}`)
        .then(res => res.json())
        .then(data => {
            const captchaDisplay = document.getElementById('captcha-display');
            const retryPrompt = document.getElementById('retry-prompt');
            
            captchaDisplay.textContent = data.captcha;
            captchaDisplay.style.display = 'block';
            retryPrompt.style.display = 'none';

            // Set timer to show expiration after 2 minutes
            const timeLeft = (data.expires_at - Date.now() / 1000) * 1000;
            captchaTimer = setTimeout(() => {
                captchaDisplay.style.display = 'none';
                retryPrompt.style.display = 'block';
            }, timeLeft);
        });
}

// Load initial captcha on page load
fetchNewCaptcha();

// Retry button click handler
document.getElementById('retry-btn').addEventListener('click', fetchNewCaptcha);
2. Setting Expiration for Retry Functions

If you're building retry logic (e.g., retrying captcha submission if it fails, or retrying generation if the request times out), you need to define an overall expiration window so retries don't run indefinitely. Here's how to implement a reusable retry wrapper:

Reusable Retry Decorator (Python Example)

import time
from functools import wraps

def retry_with_expiry(max_retries=3, total_expiry=120, base_delay=5):
    """Decorator to retry a function until success or total expiry is reached."""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            attempt = 0

            while attempt < max_retries:
                # Check if we've exceeded the total expiration window
                if time.time() - start_time > total_expiry:
                    raise TimeoutError(f"Retry expired: {func.__name__} took longer than {total_expiry}s")
                
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"Attempt {attempt + 1} failed: {str(e)}. Retrying in {base_delay}s...")
                    attempt += 1
                    time.sleep(base_delay)
                    # Optional: Use exponential backoff (e.g., base_delay * 2 ** attempt)
            
            raise Exception(f"{func.__name__} failed after {max_retries} retries")
        return wrapper
    return decorator

# Usage example
@retry_with_expiry(max_retries=3, total_expiry=120, base_delay=10)
def submit_captcha(session_id, captcha_value):
    response = requests.post('/verify-captcha', json={"session_id": session_id, "captcha": captcha_value})
    response.raise_for_status()  # Trigger error for 4xx/5xx responses
    return response.json()

# Use the function with error handling
try:
    result = submit_captcha("user-session-123", "XYZ123")
    print("Captcha verified successfully!")
except TimeoutError:
    print("Retry window expired. Please refresh and try again.")
except Exception:
    print("Captcha verification failed after all retries.")

Key Takeaways for Retry Expiration

  • Track total elapsed time: Start a timer when the retry process begins, and stop retrying if it exceeds your limit (match it to the captcha's 2-minute validity for consistency).
  • Smart delays: Use exponential backoff instead of fixed delays to reduce server load—e.g., 5s, 10s, 20s between retries.
  • Clear error signaling: Raise distinct errors for expiration vs. failed attempts so your frontend can show the right message to users.

内容的提问来源于stack exchange,提问作者cbos93

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:51:12