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

Laravel Blade模板中用jQuery播放音频遇NotAllowedError如何解决?

解决Laravel重定向后自动播放音频的NotAllowedError问题

问题场景

在Laravel项目中,客户更新表单提交后,控制器通过以下代码重定向并携带成功提示:

return redirect()->route('customer.show', $customer->id)->with('success', 'The customer has been updated successfully!');

在Blade模板中,已实现成功/错误提示的渲染:

@if(session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
    </div>
@endif
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

同时尝试在重定向后的页面自动播放提示音频,代码如下:

<audio id="successAudio" src="{{ asset('audio/success.mp3') }}" hidden></audio>
<audio id="errorAudio" src="{{ asset('audio/error.mp3') }}" hidden></audio>

<script>
    $(document).ready(function() {
        // Check for success message and play success audio
        @if(session('success'))
            $("#successAudio")[0].play();
        @endif
    
        // Check for errors and play error audio
        @if($errors->any())
            $("#errorAudio")[0].play();
        @endif
    });
</script>

但浏览器抛出错误:

Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

问题原因

现代浏览器的自动播放政策限制了页面加载时无用户交互的音频/视频自动播放,目的是避免打扰用户。只有在用户主动触发交互(如点击、触摸、键盘输入)后,浏览器才允许播放媒体内容。

解决方案

方案1:添加手动触发按钮(最稳妥)

在提示框中增加播放按钮,由用户主动点击触发音频播放,完全符合浏览器政策:

修改Blade提示代码:

@if(session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
        <button class="btn btn-sm btn-outline-primary ms-2" id="playSuccessAudio">播放提示音</button>
    </div>
@endif

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
        <button class="btn btn-sm btn-outline-danger mt-2" id="playErrorAudio">播放错误提示音</button>
    </div>
@endif

<audio id="successAudio" src="{{ asset('audio/success.mp3') }}" hidden></audio>
<audio id="errorAudio" src="{{ asset('audio/error.mp3') }}" hidden></audio>

对应的JS代码:

$(document).ready(function() {
    // 成功提示音播放
    $('#playSuccessAudio').on('click', function() {
        const audio = $("#successAudio")[0];
        audio.play().catch(err => console.error('播放失败:', err));
    });

    // 错误提示音播放
    $('#playErrorAudio').on('click', function() {
        const audio = $("#errorAudio")[0];
        audio.play().catch(err => console.error('播放失败:', err));
    });
});

方案2:利用表单提交时的用户交互提前获取权限

在用户提交表单(主动交互)时,提前尝试播放静音音频获取浏览器的播放权限,这样重定向后的页面播放音频时可能会被允许:

在原表单页面添加JS:

$('form').on('submit', function() {
    // 播放静音音频获取权限
    const tempSuccessAudio = new Audio('{{ asset('audio/success.mp3') }}');
    tempSuccessAudio.muted = true;
    tempSuccessAudio.play().then(() => {
        tempSuccessAudio.pause();
    }).catch(err => console.error('权限获取失败:', err));

    // 错误音频同理
    const tempErrorAudio = new Audio('{{ asset('audio/error.mp3') }}');
    tempErrorAudio.muted = true;
    tempErrorAudio.play().then(() => {
        tempErrorAudio.pause();
    }).catch(err => console.error('权限获取失败:', err));
});

然后重定向后的页面仍保留原播放逻辑,但需添加Promise捕获:

$(document).ready(function() {
    @if(session('success'))
        $("#successAudio")[0].play().catch(err => {
            console.error('自动播放失败,请手动点击播放:', err);
        });
    @endif

    @if($errors->any())
        $("#errorAudio")[0].play().catch(err => {
            console.error('自动播放失败,请手动点击播放:', err);
        });
    @endif
});

方案3:静音自动播放(体验有限)

将音频设置为静音后自动播放,随后取消静音(部分浏览器允许此操作),但体验可能不佳:

<audio id="successAudio" src="{{ asset('audio/success.mp3') }}" hidden muted></audio>

JS代码:

$(document).ready(function() {
    @if(session('success'))
        const audio = $("#successAudio")[0];
        audio.play().then(() => {
            // 播放后取消静音
            audio.muted = false;
        }).catch(err => console.error('播放失败:', err));
    @endif
});

注意事项

  • 所有播放操作都应添加catch处理,避免未处理的Promise拒绝错误。
  • 不同浏览器的自动播放政策略有差异,方案1的手动触发是兼容性最好的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:00:58