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

仅Safari浏览器执行函数时出现Promise未处理拒绝错误求助

错误成因分析与解决方案

根据你提供的错误信息和代码,这个Safari特有的NotSupportedError主要有以下几个可能的成因:

1. OGG音频格式支持不足

Safari(尤其是iOS Safari和旧版macOS Safari)对OGG音频格式的支持不完善,部分版本甚至完全不支持。这会导致设置音频src后无法加载资源,调用play()时触发「操作不支持」的错误。

2. Safari自动播放策略限制

Safari有严格的自动播放规则:非用户交互触发的音频/视频播放会被浏览器阻止。如果这段代码是在页面加载、定时器或其他非用户点击/触摸事件中执行的,play()方法返回的Promise会被拒绝,从而抛出Unhandled Promise Rejection错误。

3. 音频未完成加载就调用播放

直接设置src后立即调用play(),音频资源可能还没完成加载(尤其是网络较慢时),Safari此时会因为资源未就绪而抛出不支持操作的错误。


对应修复方案:

  1. 添加音频格式 fallback
    同时提供OGG和MP3格式的音频,让浏览器自动选择支持的格式:

    <!-- 替换原来的单个audio标签 -->
    <audio id="voice">
      <source src="sounds/[文件名].ogg" type="audio/ogg">
      <source src="sounds/[文件名].mp3" type="audio/mpeg">
    </audio>
    

    代码中动态生成音频源时,也需要同时添加两种格式的source标签。

  2. 确保播放触发自用户交互
    将播放逻辑包裹在用户点击/触摸事件回调中,比如绑定到你的repeat_btn点击事件:

    $("#repeat_btn").on('click', function() {
      $(this).addClass("repeat_hover");
      
      // 原有的post请求逻辑
      if (diff_lvl == 1) {
        $.post('played_games.php?diff=1', {game:"voice",post_id:<?php echo $usr_id; ?>}, function (data) {
          $('#result').html(data);
        });                                       
      } else if (diff_lvl == 3) {
        $.post('played_games.php?diff=3', {game:"voice",post_id:<?php echo $usr_id; ?>}, function (data) {
          $('#result').html(data);
        }); 
      }
      
      // 音频播放逻辑
      var count = array_voices_hashes.length;
      var newpic_onload = Math.floor(Math.random() * count);
      var randompic_onload = array_voices_hashes[newpic_onload];
      
      var audio = document.getElementById("voice");
      // 清空原有source
      audio.innerHTML = '';
      // 添加双格式源
      var oggSource = document.createElement('source');
      oggSource.src = 'sounds/' + randompic_onload + '.ogg';
      oggSource.type = 'audio/ogg';
      var mp3Source = document.createElement('source');
      mp3Source.src = 'sounds/' + randompic_onload + '.mp3';
      mp3Source.type = 'audio/mpeg';
      audio.appendChild(oggSource);
      audio.appendChild(mp3Source);
      
      // 等待音频加载完成再播放
      audio.addEventListener('canplaythrough', function playAudio() {
        audio.play().catch(function(err) {
          // 捕获播放错误,避免未处理的Promise拒绝
          console.error('播放失败:', err);
        });
        audio.removeEventListener('canplaythrough', playAudio);
      });
      
      cdreset();
      countdown();
    });
    
  3. 捕获play()的Promise异常
    即使做了上述处理,仍需主动捕获play()返回的Promise错误,避免控制台抛出未处理的拒绝:

    document.getElementById("voice").play().catch(function(error) {
      console.error('音频播放失败:', error);
      // 可在此添加降级处理,比如提示用户手动点击播放
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:57:29