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

使用WebOTP API遇DOMException: OTP retrieval was cancelled问题排查

问题分析与解决步骤

一、页面加载时「OTP retrieval was cancelled」异常的原因及修复

这个错误核心是useEffect未设置依赖数组,导致组件每次渲染都会重复调用navigator.credentials.get,新创建的AbortController会终止之前未完成的请求,进而抛出取消异常。

修复方法:
给useEffect添加空依赖数组,确保仅在组件挂载时执行一次逻辑,同时优化异常处理逻辑:

useEffect(() => {
    if ('OTPCredential' in window) {
        const input = document.querySelector<HTMLInputElement>(
            'input[name="code-input-0"]',
        );
        if (!input) return;
        const ac = new AbortController();
        navigator.credentials
            .get({
                otp: { transport: ['sms'] },
                signal: ac.signal,
            })
            .then(otp => {
                input.value = otp!.code;
                ac.abort();
            })
            .catch(err => {
                console.error(err);
                // 仅在非终止错误时执行abort,避免重复操作
                if (err.name !== 'AbortError') {
                    ac.abort();
                }
            });
        
        // 组件卸载时主动终止请求
        return () => ac.abort();
    }
}, []); // 添加空依赖数组,限制执行时机

二、点击授权后无反应的原因及修复

1. 调整短信格式

WebOTP API要求目标域名必须紧跟在#验证码之前,由于验证码需要填充到跨域iframe内,需将iframe域名放在#前,主域名可作为额外域名补充:

Your OTP is: 12345
@iframe-domain.com #12345 @top-level-domain.com

这样浏览器才能正确识别验证码的目标页面(iframe内的应用)。

2. 完善跨域iframe权限配置

除了给iframe添加allow='otp-credentials',还需检查:

  • 若iframe设置了sandbox属性,需确保包含allow-scripts和allow-same-origin,否则会限制WebOTP API调用;
  • iframe页面必须使用HTTPS协议(或localhost),WebOTP仅支持安全上下文。

3. 确保输入框可被正确获取

如果输入框是动态渲染的,建议使用useRef替代querySelector,更可靠地绑定输入元素:

const codeInputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
    if ('OTPCredential' in window && codeInputRef.current) {
        const ac = new AbortController();
        navigator.credentials
            .get({
                otp: { transport: ['sms'] },
                signal: ac.signal,
            })
            .then(otp => {
                codeInputRef.current!.value = otp!.code;
                ac.abort();
            })
            .catch(err => {
                console.error(err);
                if (err.name !== 'AbortError') {
                    ac.abort();
                }
            });
        
        return () => ac.abort();
    }
}, []);

// 输入框绑定ref
<input ref={codeInputRef} name="code-input-0" type="text" />

三、额外注意事项

  • 测试需使用真实短信或Chrome DevTools模拟短信,不可手动修改格式;
  • 确保Chrome版本在84及以上,支持WebOTP API;
  • 若为多层嵌套iframe,每一层都需添加allow='otp-credentials'属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 13:34:57