使用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
相关产品推荐
相关产品推荐

