无需刷新页面重新加载音频缓存(Node.js+Express+前端JS)
解决音频更新后无需刷新页面即可重新加载的问题
问题背景
我搭建了Node.js Express服务器及JS-HTML-CSS网页,可从服务器获取音频流并在网页播放,但存在一个问题:当音频更新后,必须刷新页面才能听到新音频。如何实现点击按钮时重置缓存并重新加载音频?
解决方案
要解决缓存问题,需要从前端绕过缓存请求新资源和后端禁止缓存响应两方面入手:
1. 前端代码修改
先给音频标签添加ID方便JS操作;再在按钮点击事件中,通过给音频URL添加时间戳参数强制请求新资源,并重新加载音频。
修改后的HTML音频标签
<audio id="audioPlayer" controls="controls"> <source src="http://localhost:8080/stream" type="audio/ogg" preload="metadata" /> <source src="http://localhost:8080/stream" type="audio/mpeg" preload="metadata" /> </audio>
修改后的前端JS
window.onload = function(){ const mb = document.getElementById('firstbutton'); mb.addEventListener('click', triggerFUN); } async function triggerFUN(){ const input = document.getElementById("uniqueID"); const value = input ? input.value : ''; document.getElementById("first").innerHTML = value; // 发送POST请求到后端 const xhr = new XMLHttpRequest(); const yourUrl = "http://localhost:8080/index"; xhr.open("POST", yourUrl, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify({ value: value })); // 重新加载音频资源(绕过缓存) const audioPlayer = document.getElementById('audioPlayer'); const sources = audioPlayer.querySelectorAll('source'); sources.forEach(source => { // 移除旧缓存参数,添加当前时间戳作为新参数 const baseUrl = source.src.split('?')[0]; source.src = `${baseUrl}?t=${Date.now()}`; }); // 触发音频加载并尝试播放 audioPlayer.load(); audioPlayer.play().catch(err => console.error('音频播放失败:', err)); console.log(value); }
2. 后端代码修改
在音频流接口中添加缓存控制响应头,明确禁止浏览器和中间缓存存储旧音频文件。
修改后的Express /stream 端点
const fs = require('fs'); app.get('/stream', (req, res) => { const file = __dirname + '/output.mp3'; fs.exists(file, (exists) => { if (exists) { // 设置禁止缓存的响应头 res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); res.setHeader('Pragma', 'no-cache'); res.setHeader('Expires', '0'); const rstream = fs.createReadStream(file); rstream.pipe(res); } else { res.status(404).send('Error - 404'); res.end(); } }); });
原理说明
- 前端时间戳参数:每次请求的URL会因时间戳不同被浏览器视为新资源,彻底绕过本地缓存。
- 后端缓存头:通过
Cache-Control等头信息,强制浏览器每次向服务器请求最新音频,避免中间代理缓存旧资源。 audio.load()方法:触发音频元素重新加载所有source资源,确保播放的是最新音频。
内容的提问来源于stack exchange,提问作者demonjoseph
相关产品推荐
相关产品推荐

