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

