当前位置: 首页 > news >正文

JavaScript 接收并解析后端发送的 JSON 数据,同时将数据以美观的方式展示在页面上

JavaScript 实现代码

这段代码包含 WebSocket 连接管理、JSON 解析和 UI 渲染逻辑:

// WebSocket 连接管理
let socket;
const messageContainer = document.getElementById('message-container');
const socketStatus = document.getElementById('socket-status');
const connectBtn = document.getElementById('connect-btn');
const lastUpdate = document.getElementById('last-update');// 连接 WebSocket
function connectWebSocket() {// 关闭现有连接(如果存在)if (socket && socket.readyState !== WebSocket.CLOSED) {socket.close();}// 创建新连接socket = new WebSocket('ws://localhost:8080/websocket');// 更新 UI 状态socketStatus.innerHTML = '<i class="fa fa-circle-o-notch fa-spin mr-2"></i>连接中...';socketStatus.classList.remove('disconnected', 'connected');connectBtn.disabled = true;connectBtn.innerHTML = '<i class="fa fa-circle-o-notch fa-spin mr-2"></i>连接中...';// 监听连接成功socket.onopen = () => {messageContainer.innerHTML = '';socketStatus.innerHTML = '<i class="fa fa-check-circle mr-2"></i>已连接';socketStatus.classList.add('connected');connectBtn.innerHTML = '<i class="fa fa-plug mr-2"></i>断开连接';connectBtn.disabled = false;connectBtn.classList.remove('bg-primary');connectBtn.classList.add('bg-red-500', 'hover:bg-red-600');appendSystemMessage('WebSocket 连接已建立');};// 监听消息接收socket.onmessage = (event) => {try {// 解析 JSON 数据const jsonData = JSON.parse(event.data);// 更新最后更新时间const now = new Date();lastUpdate.textContent = now.toLocaleString();// 格式化显示数据const messageDiv = document.createElement('div');messageDiv.className = 'message-card';messageDiv.style.opacity = '0';messageDiv.style.transform = 'translateY(10px)';messageDiv.style.transition = 'opacity 0.3s ease, transform 0.3s ease';// 动态生成内容let contentHtml = '';for (const [key, value] of Object.entries(jsonData)) {if (typeof value === 'object' && value !== null) {// 嵌套对象处理contentHtml += `<p><strong>${formatKey(key)}:</strong></p>`;contentHtml += '<div class="ml-4 bg-gray-50 p-3 rounded my-2">';for (const [nestedKey, nestedValue] of Object.entries(value)) {contentHtml += `<p class="text-sm"><strong>${formatKey(nestedKey)}:</strong> ${formatValue(nestedValue)}</p>`;}contentHtml += '</div>';} else {// 普通字段处理contentHtml += `<p><strong>${formatKey(key)}:</strong> ${formatValue(value)}</p>`;}}messageDiv.innerHTML = contentHtml;messageContainer.prepend(messageDiv);// 添加动画效果setTimeout(() => {messageDiv.style.opacity = '1';messageDiv.style.transform = 'translateY(0)';}, 10);} catch (error) {console.error('解析 JSON 失败:', error);appendError(`解析消息失败: ${error.message}`);}};// 监听连接关闭socket.onclose = (event) => {socketStatus.innerHTML = '<i class="fa fa-times-circle mr-2"></i>已断开';socketStatus.classList.remove('connected');socketStatus.classList.add('disconnected');connectBtn.innerHTML = '<i class="fa fa-plug mr-2"></i>连接';connectBtn.disabled = false;connectBtn.classList.remove('bg-red-500', 'hover:bg-red-600');connectBtn.classList.add('bg-primary');appendSystemMessage(`WebSocket 连接已关闭 (代码: ${event.code})`);};// 监听错误socket.onerror = (error) => {console.error('WebSocket 错误:', error);appendError(`WebSocket 错误: ${error.message}`);};
}// 格式化键名(将 camelCase 转为空格分隔的标题格式)
function formatKey(key) {return key.replace(/([A-Z])/g, ' $1').replace(/^./, (str) => str.toUpperCase());
}// 格式化值(处理特殊类型)
function formatValue(value) {if (typeof value === 'number' && !isNaN(value)) {return value;} else if (typeof value === 'boolean') {return value ? '<span class="text-green-600">是</span>' : '<span class="text-red-600">否</span>';} else if (value === null || value === undefined) {return '<span class="text-gray-400">null</span>';} else if (typeof value === 'string') {// 尝试解析为日期const date = new Date(value);if (!isNaN(date.getTime())) {return date.toLocaleString();}return value;}return JSON.stringify(value);
}// 添加系统消息
function appendSystemMessage(message) {const systemMessage = document.createElement('div');systemMessage.className = 'text-center text-gray-500 italic py-2';systemMessage.innerHTML = `<i class="fa fa-info-circle mr-1"></i> ${message}`;messageContainer.prepend(systemMessage);
}// 添加错误消息
function appendError(message) {const errorDiv = document.createElement('div');errorDiv.className = 'error-card';errorDiv.innerHTML = `<p><i class="fa fa-exclamation-triangle mr-1"></i> ${message}</p>`;messageContainer.prepend(errorDiv);
}// 连接按钮事件
connectBtn.addEventListener('click', () => {if (socket && socket.readyState === WebSocket.OPEN) {socket.close();} else {connectWebSocket();}
});// 页面加载时自动连接
window.addEventListener('load', connectWebSocket);

HTML 结构(需配合上述 JS 使用)

完整的 HTML 页面结构,包含 Tailwind CSS 和 Font Awesome 引入:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebSocket JSON 消息接收</title><script src="https://cdn.tailwindcss.com"></script><link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"><script>tailwind.config = {theme: {extend: {colors: {primary: '#165DFF',secondary: '#36CFC9',neutral: '#F5F7FA',dark: '#1D2129',},fontFamily: {inter: ['Inter', 'system-ui', 'sans-serif'],},}}}</script><style type="text/tailwindcss">@layer utilities {.content-auto {content-visibility: auto;}.message-card {@apply bg-white rounded-lg shadow-md p-4 mb-4 transition-all duration-300 hover:shadow-lg border-l-4 border-primary;}.error-card {@apply bg-red-50 border-l-4 border-red-400 text-red-700 p-4 mb-4 rounded-r shadow-md;}.socket-status {@apply fixed top-4 right-4 px-4 py-2 rounded-full text-sm font-medium transition-all duration-300 z-50;}.socket-status.connected {@apply bg-green-100 text-green-800 border border-green-400;}.socket-status.disconnected {@apply bg-red-100 text-red-800 border border-red-400;}}</style>
</head>
<body class="bg-gray-50 font-inter text-dark min-h-screen"><div class="container mx-auto px-4 py-8 max-w-5xl"><header class="mb-8"><h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-primary mb-2">WebSocket JSON 消息接收</h1><p class="text-gray-600">实时接收并解析后端发送的 JSON 数据</p></header><!-- 状态指示器 --><div id="socket-status" class="socket-status disconnected"><i class="fa fa-circle-o mr-2"></i>未连接</div><!-- 消息容器 --><div class="bg-white rounded-xl shadow-lg p-6 mb-6"><h2 class="text-xl font-semibold mb-4 flex items-center"><i class="fa fa-comments-o text-primary mr-2"></i>消息记录</h2><div id="message-container" class="space-y-4 max-h-[60vh] overflow-y-auto p-2"><div class="text-center text-gray-500 italic py-8">等待 WebSocket 连接...</div></div></div><!-- 控制按钮 --><div class="flex justify-between items-center"><button id="connect-btn" class="px-6 py-3 bg-primary hover:bg-primary/90 text-white rounded-lg shadow transition-all duration-300 flex items-center"><i class="fa fa-plug mr-2"></i>连接</button><div class="text-sm text-gray-500"><i class="fa fa-clock-o mr-1"></i>最后更新: <span id="last-update">-</span></div></div></div><!-- 这里插入上面的 JavaScript 代码 --><script>// 上面的 JS 代码放在这里</script>
</body>
</html>

核心功能说明

WebSocket 连接管理

  • 使用 WebSocket 构造函数创建连接
  • 监听 onopenonmessageonclose 和 onerror 事件
  • 提供连接 / 断开切换按钮

JSON 解析

  • 使用 JSON.parse() 解析后端发送的字符串
  • 处理嵌套 JSON 结构
  • 类型安全检查和错误处理

UI 渲染

  • 使用 Tailwind CSS 实现现代卡片式布局
  • 动态生成 HTML 内容
  • 添加消息动画和状态指示器
  • 响应式设计适配各种屏幕尺寸

用户体验优化

  • 连接状态实时显示
  • 消息接收时间戳
  • 错误提示和友好反馈
  • 平滑过渡动画

将上述代码保存为 HTML 文件后,在浏览器中打开即可使用。确保后端 WebSocket 服务在 ws://localhost:8080/websocket 可用,或根据实际情况修改连接地址。

相关文章:

  • Kotlin-类和对象
  • TCP首部格式及三次握手四次挥手
  • 【学习笔记】Shell编程---流程控制语句
  • 【用「概率思维」重新理解生活】
  • 深入探讨 Java 性能术语与优化实践
  • 12.1寸工业液晶屏M121XGV20-N10显示单元技术档案
  • ubuntu22.04编译PX4无人机仿真实践
  • Git命令起别名
  • Cursor开发酒店管理系统
  • 【AI论文】健康的大型语言模型(LLMs)?——评估大型语言模型对英国政府公共健康信息的掌握程度
  • 什么是序列化与反序列化
  • Kubernetes 标签和注解
  • Unity
  • [ linux-系统 ] 进程概念与基本操作
  • 【大模型】DeepResearcher:通用智能体通过强化学习探索优化
  • 嵌入式STM32学习——外部中断EXTI与NVIC的基础练习⭐
  • 大便次数与寿命有关?
  • 通过SSRF击穿内网!kali-ssrf靶场实战!
  • 基于MNIST数据集的手写数字识别(简单全连接网络)
  • 蓝桥杯 16. 外卖店优先级
  • 中哥两国元首共同见证签署《中华人民共和国政府与哥伦比亚共和国政府关于共同推进丝绸之路经济带和21世纪海上丝绸之路建设的合作规划》
  • “典孝急乐批麻蚌赢”:互联网“八字真言”与当代赛博赢学
  • 《克莱默夫妇》导演罗伯特·本顿去世,终年92岁
  • 乌拉圭前总统何塞·穆希卡去世
  • 夜读|尊重生命的棱角
  • “远践”项目启动公益生态圈,上海青少年公益力量蓬勃生长