如何在JavaScript中将Icecast服务器返回的远程JSON对象转为数组
解决Icecast JSON数据转换与听众数展示问题
我来帮你搞定这个问题!你现在的代码确实会把整个Icecast返回的JSON对象当成单个元素塞进数组里,这可不是你想要的效果——毕竟扩展运算符只对数组生效,自然用不了。咱们一步步来修正:
先搞懂Icecast返回的JSON结构
Icecast的status-json.xsl接口返回的结构大概是这样的(简化版):
{ "icestats": { "source": [ { "listeners": 123, "server_name": "My Radio Stream", // 其他字段... } ] } }
如果服务器只有一个流,source可能会是单个对象而不是数组,这点要提前处理。
修正你的JS代码
我们需要提取出里面的source数据(流的列表),把它转成可靠的数组,再赋值给serverStats:
const endpoint = 'http://stream.8k.nz:8000/status-json.xsl'; let serverStats = []; fetch(endpoint) .then(blob => blob.json()) .then(data => { // 处理source:如果是单个对象就转成数组,已经是数组就直接用 const sources = Array.isArray(data.icestats.source) ? data.icestats.source : [data.icestats.source]; // 替换serverStats为流数组,而不是把整个JSON塞进去 serverStats = sources; // 现在可以调用展示函数了 displayListenerStats(); }) .catch(err => console.error('获取数据失败:', err));
编写HTML展示逻辑
接下来写一个函数把听众数展示到页面上,比如假设你有一个id为listener-stats的容器:
function displayListenerStats() { const statsContainer = document.getElementById('listener-stats'); // 清空容器 statsContainer.innerHTML = ''; serverStats.forEach(source => { const statItem = document.createElement('div'); statItem.innerHTML = ` <h3>${source.server_name}</h3> <p>当前听众数: <strong>${source.listeners}</strong></p> `; statsContainer.appendChild(statItem); }); }
对应的HTML结构示例:
<div id="listener-stats"></div>
关键要点总结
- 不要把整个返回的JSON对象塞进数组,而是提取里面的
source字段(真正包含流统计的部分) - 一定要处理
source是单个对象的情况,用Array.isArray()判断后转成数组,避免后续遍历出错 - 数据获取完成后再调用展示函数,确保
serverStats已经有有效数据
内容的提问来源于stack exchange,提问作者Dr Hitchcock
相关产品推荐
相关产品推荐

