本篇为物联网项目前端开发核心实战内容,聚焦IoT数据可视化大屏、设备控制交互、告警历史数据、API与MQTT/WebSocket联调四大核心模块,贴合企业工业级开发规范,包含完整技术原理、落地代码、性能优化、容错策略与联调踩坑方案,适合物联网前端开发、毕设项目、企业实战落地参考。
一、设备数据展示 Dashboard(IoT可视化大屏核心)
物联网设备会不间断产生温度、湿度、电压、设备状态、在线数量、负载等零散数据,大屏前端的核心价值是将后端、设备上传的海量数字数据,转化为可视化图表、数字面板、设备地图、告警列表,让运维人员直观查看设备实时状态、数据变化与异常信息。
1. WebSocket 实时数据推送接入
(1)核心定义
WebSocket 是 HTML5 规范提供、基于TCP协议的全双工、持久长连接通信协议,完美适配物联网实时数据推送场景。
-
普通HTTP:短连接,前端主动请求、后端被动响应,请求结束立即断联,无法适配实时场景
-
WebSocket:长连接,页面挂载后持续连通,服务端有新数据可主动推送,无需前端轮询请求
(2)协议端口与前缀规范
-
开发/测试环境:ws:// 明文协议,常用端口 8080、80
-
生产线上环境:wss:// 加密协议(适配HTTPS),常用端口443,为企业生产唯一推荐方案
(3)HTTP与WebSocket核心区别
|
连接类型 |
短连接,请求完成立即断开 |
长连接,页面活跃状态持续连通 |
|
通信方式 |
单向通信,仅前端主动请求 |
全双工通信,前后端可双向主动发数据 |
|
会话状态 |
无状态,服务端不保留客户端会话 |
维持长连接会话,支持有状态业务 |
|
适用场景 |
静态页面访问、常规接口查询 |
IoT实时监控、即时通讯、设备数据推送 |
(4)WebSocket核心事件(覆盖99%物联网场景)
-
onopen:连接成功建立时触发一次
-
onmessage:核心事件,服务端推送数据时触发,是前端接收设备数据的唯一入口
-
onerror:网络异常、地址错误、服务报错时触发
-
onclose:连接关闭、网络断开、服务下线时触发
(5)readyState 四种连接状态
用于实时判断连接状态,是断线重连、状态校验的核心依据:
-
0 CONNECTING:正在建立连接
-
1 OPEN:连接成功,正常通信(稳定工作状态)
-
2 CLOSING:正在关闭连接
-
3 CLOSED:连接彻底断开/关闭
(6)数据传输规范
WebSocket仅支持纯文本字符串、二进制数据两种格式,物联网行业统一规范:
-
前后端统一传输 JSON字符串 格式数据
-
前端接收数据:通过 JSON.parse() 将字符串转为JS对象读取字段
-
前端发送数据:通过 JSON.stringify() 将JS对象转为字符串传输
(7)工业级三大核心容错策略
① 断线重连机制
触发场景:网络波动、服务器重启、电脑休眠唤醒、后台服务更新
开发规范:连接关闭/报错自动触发重连;入门可采用3秒固定间隔、最大10次重连;工业级推荐指数退避+随机间隔重连,避免大量客户端同时重连冲垮服务。
② 心跳保活机制
路由器、防火墙会自动清理长时间无交互的空闲长连接,导致页面显示连接正常但实际断连。浏览器无原生Ping包,项目均使用应用层心跳:
-
前端每30秒主动推送心跳包:{"type":"heartbeat"}
-
后端接收后返回确认信息
-
超时未确认则判定掉线,自动触发重连
③ 数据异常捕获容错
规避异常数据导致页面崩溃,保障系统稳定性:
-
非标准JSON数据:直接跳过,不解析、不抛错
-
核心字段缺失:填充兜底值(– / 0)
-
单条异常数据不影响页面整体运行与后续接收
2. ECharts 实时数据图表可视化
Apache ECharts 是百度开源、Apache基金会孵化的可视化库,基于Canvas/SVG渲染,是国内IoT大屏、数据中台主流可视化解决方案。
(1)IoT大屏常用可视化组件
-
折线图:展示温度、湿度、电压等连续变化的趋势数据
-
仪表盘Gauge:展示设备负载、电量、在线率等瞬时百分比数据
-
地图:展示设备地理位置分布、区域设备统计数据
-
拓展组件:柱状图、饼图、数字统计卡片、设备告警列表、状态看板
(2)ECharts官方开发四大核心原则
-
原则1:单例初始化+销毁释放:组件挂载仅初始化一次图表,Vue/React组件销毁时调用 dispose() 释放内存,杜绝内存泄漏、页面卡顿
-
原则2:setOption增量更新:数据更新仅修改配置与数据,不重建画布,保障实时更新流畅度
-
原则3:限制历史数据长度:常规场景保留20-30条历史数据,避免数据无限堆积导致内存溢出、渲染卡顿
-
原则4:监听resize重绘:窗口缩放、分辨率切换时调用 resize() 重绘,防止图表变形、溢出
3. 大屏自适应布局方案(rem/vw/scale)
物联网大屏通用设计基准为1920×1080(16:9),需兼容2K/4K屏、竖屏、超宽拼接屏等非标设备,主流三种自适应方案如下:
(1)vw/vh 视口单位(纯CSS方案)
vw、vh为浏览器原生比例单位,1vw=屏幕宽度1%,1vh=屏幕高度1%,无需JS即可实现自适应。
-
核心区别:vw/vh随屏幕缩放,px尺寸固定不变
-
搭配规则:整体布局、文字、间距用vw/vh;线条、阴影、细节用px
-
优缺点:纯CSS实现、适配灵活,但宽高独立计算易变形
-
适用场景:快速Demo、简单大屏、对比例要求不高的项目
/* 设计稿1920×1080换算规则 */
.box {
width: 50vw; /* 960px ÷ 19.2 = 50vw */
height: 30vh; /* 324px ÷ 10.8 = 30vh */
font-size: 2vw; /* 38.4px ÷ 19.2 = 2vw */
border: 1px solid #fff;
box-shadow: 0 2px 10px #000;
}
(2)rem 适配(企业正式项目首选)
rem大小由html根字体大小决定,全局统一基准,实现页面等比例缩放,不变形、易维护。
-
核心规则:1rem = html根字体大小,全局统一缩放
-
换算规则:设计稿px值 ÷ 19.2 得到rem值
-
优缺点:规则统一、稳定不变形、维护性强,需手动单位换算
-
适用场景:企业物联网Dashboard、正式线上监控大屏
html {
font-size: 1vw; /* 1rem = 1vw,统一全局基准 */
}
.box {
width: 20.8rem; /* 400px ÷ 19.2 */
height: 15rem; /* 288px ÷ 19.2 */
}
(3)scale 整体缩放(展厅演示大屏首选)
将页面固定设计稿尺寸,通过JS计算比例整体缩放,所有元素比例完全不变,100%还原设计稿。
-
核心规则:页面写死1920×1080,所有元素直接用px,JS动态缩放适配屏幕
-
优缺点:零换算、完全不变形;屏幕比例不匹配会留白,缩放过度易模糊
-
适用场景:展厅大屏、演示项目、严格还原设计稿的场景
/* 固定外层容器尺寸 */
.wrap {
width: 1920px;
height: 1080px;
}
.box {
width: 400px;
height: 288px;
}
// JS动态计算缩放比例
let scale = window.innerWidth / 1920
document.querySelector('.wrap').style.transform = `scale(${scale})`
(4)三种适配方案对比总结
|
vw/vh |
屏幕百分比独立适配宽高 |
需要 |
易变形 |
简单页面、快速Demo |
|
rem |
全局统一基准等比缩放 |
需要 |
基本不变形 |
企业正式IoT大屏、监控平台 |
|
scale |
页面整体图片式缩放 |
无需 |
完全不变形 |
展厅演示、高还原设计稿场景 |
4. 数据刷新与异常断线重连策略
4.1 数据刷新策略
实现页面数据自动更新,无需人工刷新,分为两种主流方案:
(1)定时轮询(企业中等实时场景首选)
固定间隔自动请求后端接口,更新页面数据,实现简单、兼容性强、稳定性高。
核心规则:页面加载立即刷新一次、固定间隔请求、异常不中断、页面销毁清除定时器、避免并发请求。
let timer = null
// 启动数据刷新
function startRefresh() {
getData() // 初始立即执行
timer = setInterval(getData, 5000) // 5秒轮询一次
}
// 请求数据
async function getData() {
try {
const res = await fetch('/api/data')
const data = await res.json()
render(data) // 页面渲染
} catch (err) {
console.log('数据请求异常', err)
}
}
// 页面卸载清除定时器,防止内存泄漏
window.onbeforeunload = () => clearInterval(timer)
startRefresh()
(2)WebSocket长连接(高实时场景首选)
服务端有新数据主动推送,前端即时更新,无延迟、无无效请求,适配高频数据、告警推送场景。
4.2 异常断线重连策略(高可用核心)
解决网络断开、服务异常、接口报错导致的页面断连问题,实现自动恢复,无需人工刷新。
核心原则
-
异常必捕获,不崩溃页面
-
失败自动重试,非单次请求
-
指数退避重试,避免压垮服务器
-
限制最大重试次数,防止无限请求
-
重连成功重置状态、清零次数
-
监听网络恢复,立即触发重连
关键策略
全局try/catch异常捕获、指数退避重连、最大次数限制、网络状态监听、重连成功重置机制。
二、设备控制交互界面
设备控制界面用于远程操控物联网设备、展示操作结果、区分账号权限,适配电脑/移动端,核心要求:防误操作、反馈清晰、权限隔离、多端适配,分为指令下发、状态反馈、权限控制、移动端适配四大模块。
1. 设备指令下发前端交互设计
1.1 基础概念
前端点击按钮下发开机、关机、摄像头转动、参数修改、设备重启等指令,由后端转发至现场设备执行。不同设备适配不同传输协议:
-
监控摄像头:国标控制协议
-
普通IoT设备:WebSocket长连接/HTTP接口下发
-
工厂PLC工控设备:工业专用传输协议
-
所有操作生成唯一指令编号,用于故障排查与审计溯源
1.2 典型交互流程
(1)操作前置校验
-
设备状态校验:离线设备操作按钮置灰,hover提示无法操作
-
二次确认弹窗:断电、批量重启等高危操作弹窗确认,普通参数调节无需弹窗
-
参数校验:前端拦截超限参数,不传递无效请求至后端
(2)指令发送与并发约束
-
互斥操作禁用:如制冷/制热模式无法同时开启,操作互斥按钮自动置灰
-
防重复点击:上一条指令未响应前,锁定按钮避免重复下发
-
无冲突操作可并行执行,无需排队
(3)操作记录留存
前端缓存会话内操作记录,正式审计日志(账号、时间、设备、指令、IP、结果)由后端持久化存储,前端仅负责查询展示。
1.3 界面组件设计规范
-
单设备控制:开关、滑动条、云台方向按键
-
批量管控:设备复选框+批量操作按钮
-
定时任务:弹窗表单配置定时指令
-
异常状态:离线、无权限控件置灰,搭配锁形图标与hover提示
2. 操作状态反馈(Loading/Success/Error)
所有操作必须有可视化反馈,杜绝无响应交互:
-
加载中:按钮loading转圈、锁定防重复点击,批量操作页面局部遮罩提示
-
操作成功:普通操作右下角轻提示自动消失;高危/批量操作弹窗提示,同步更新设备状态
-
操作失败:参数错误输入框红字提示;设备离线/权限不足弹窗展示原因+指令编号;网络异常支持重试,硬件故障永久锁定按钮
-
批量操作:明确展示全部成功/全部失败/部分异常,异常设备标红高亮
3. 权限控制(操作人员VS管理员)
行业通用规则:前端仅做视觉限制,后端二次接口校验,杜绝越权操作。
普通操作人员
-
只读账号:仅查看设备状态,所有操作按钮置灰
-
基础账号:仅单设备启停、微调参数,无批量控制、定时任务、高危操作权限
-
仅可查看、操作个人负责设备
管理员账号
拥有全量权限:单/批量设备控制、定时任务配置、高危停机操作、查看全员操作日志、日志导出、权限分配。
统一交互规则
无权限按钮置灰加锁不隐藏;非法路由跳转自动回首页并提示无权限。
4. 移动端H5响应式适配
兼容手机、平板访问,保留核心查看与基础操作功能,适配触屏交互;权限规则、状态反馈、交互逻辑与PC端完全统一,仅布局自适应缩放,后端权限校验逻辑通用。
三、告警与历史数据模块
1. 告警列表(实时推送+历史记录)
物联网设备7×24小时运行,会产生故障、超限、离线、低压等异常告警,分为实时告警推送和历史告警记录,是故障排查核心依据。
(1)实时告警推送(WebSocket长连接)
实时告警对延迟要求极高,摒弃轮询方案,采用WebSocket长连接实现秒级推送:服务端产生告警后主动推送前端,无延迟、无无效请求。
前端交互规范
新告警置顶、红点高亮、声音提示、动态刷新列表,不重载整页;支持断线自动重连、离线告警补拉、网络波动数据缓存。
Vue核心实现代码
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const alarmList = ref([])
let socket = null
let reconnectTimer = null
// 初始化告警WebSocket连接
function initWs() {
socket = new WebSocket('ws://localhost:8080/iot/alarm')
// 连接成功
socket.onopen = () => {
clearTimeout(reconnectTimer)
console.log('告警ws连接成功')
}
// 接收实时告警数据
socket.onmessage = (res) => {
const alarm = JSON.parse(res.data)
alarmList.value.unshift(alarm) // 新告警置顶
}
// 断开自动重连
socket.onclose = () => {
reconnectTimer = setTimeout(() => initWs(), 3000)
}
}
onMounted(() => initWs())
onUnmounted(() => {
clearTimeout(reconnectTimer)
socket?.close()
})
</script>
(2)历史告警记录(HTTP分页查询)
历史数据无需实时推送,采用普通HTTP接口按需查询,节省服务端资源。
核心字段
告警时间、设备ID、设备名称、告警类型、告警级别、告警内容、处理状态、处理人
筛选与状态规范
-
筛选条件:时间范围、设备、告警级别、处理状态
-
告警级别:紧急(红)、重要(橙)、一般(黄)、提示(蓝)
-
状态流转:未处理、处理中、已恢复、已忽略
分页查询代码
async function getHistoryAlarm(params) {
const res = await fetch('/api/alarm/history', {
method: 'POST',
body: JSON.stringify(params)
})
return await res.json()
}
2. 时间筛选与历史趋势图
通过时间区间筛选时序数据,搭配趋势图可视化温湿度、电压等数据变化,用于故障复盘与数据分析。
2.1 时间范围筛选规范
通用筛选维度
-
快捷选项:今日、昨日、近7天、近30天、本月、上月
-
自定义选项:自定义起止时间(精确到秒)
前端传参核心规范
禁止传本地格式化字符串,统一使用Unix时间戳/ISO8601 UTC标准时间,无时区歧义,避免后端解析异常。
时间处理工具代码
// 日期转毫秒时间戳
function dateToTimestamp(date) {
return new Date(date).getTime()
}
// 日期转ISO8601 UTC标准格式
function dateToUTC(date) {
return new Date(date).toISOString()
}
// 时间区间合法性校验
function checkTimeRange(startTime, endTime) {
const start = new Date(startTime).getTime()
const end = new Date(endTime).getTime()
if (end < start) {
alert('结束时间不能早于开始时间')
return false
}
// 限制最大查询90天数据,防止数据量过大
const maxDay = 90 * 24 * 60 * 60 * 1000
if (end – start > maxDay) {
alert('查询区间不能超过90天')
return false
}
return true
}
2.2 历史趋势图可视化
技术栈选型
-
PC端大屏:优先ECharts(支持3D图表,适配复杂可视化)
-
移动端H5/小程序:优先AntV F2(轻量化、触控流畅)
核心业务图表
-
折线图:设备参数连续趋势变化
-
阶梯图:设备启停状态切换记录
-
多维度对比图:多设备、多参数数据对比
-
3D拓展图表(ECharts-GL):3D温度走势、空间设备点位分布
核心优化:数据降采样
设备秒级采集单日数据可达上万条,前端直接渲染会卡顿崩溃。需后端做降采样处理,抽取均值、峰值精简数据,保留核心趋势,是物联网图表必备优化。
ECharts趋势图完整代码(含内存释放)
<template>
<div ref="chartRef" style="width:100%;height:400px;"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
const chartRef = ref(null)
let chartInstance = null
// 销毁图表实例,释放内存
function disposeChart() {
if (chartInstance) {
chartInstance.dispose()
chartInstance = null
}
}
// 渲染趋势图
function renderChart(data) {
disposeChart()
chartInstance = echarts.init(chartRef.value)
const option = {
xAxis: { type: 'category', data: data.timeList },
yAxis: { type: 'value', name: '温度℃' },
series: [{ type: 'line', data: data.tempList }]
}
chartInstance.setOption(option)
}
// 窗口重绘
function handleResize() {
chartInstance?.resize()
}
onMounted(() => window.addEventListener('resize', handleResize))
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
disposeChart()
})
</script>
3. CSV/Excel数据导出功能
用于设备日志、告警记录、历史数据本地存档与报表统计,两种格式适配不同场景。
3.1 格式场景区分
-
CSV格式:轻量、导出速度快、无卡顿,适配几万条海量日志数据,物联网项目优先使用
-
Excel格式:支持复杂样式、多工作表,适配正式办公报表、汇报场景
3.2 技术实现方案
核心依赖:xlsx(数据处理)、file-saver(文件保存)
-
前端导出:1万条以内少量数据,前端直接生成,速度快
-
后端导出:1万条以上海量数据,后端生成文件返回下载链接,避免前端内存溢出
核心导出代码
import * as XLSX from 'xlsx'
import { saveAs } from 'file-saver'
// 前端导出CSV
function exportCSV(tableData, fileName) {
const ws = XLSX.utils.json_to_sheet(tableData)
const wb = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(wb, ws, '告警记录')
const csvBuf = XLSX.write(wb, { bookType: 'csv', type: 'buffer' })
saveAs(new Blob([csvBuf]), `${fileName}.csv`)
}
// 海量数据后端导出
async function bigDataExport(params) {
const res = await fetch('/api/alarm/export', {
method: 'POST',
body: JSON.stringify(params)
})
const { downloadUrl } = await res.json()
window.open(downloadUrl)
}
3.3 企业级规范
导出文件名包含项目名、设备名、时间区间、导出时间;自动格式化时间、转换状态码、空值兜底;无权限按钮置灰,导出过程展示loading防重复点击。
4. 虚拟列表渲染优化(海量数据必备)
常规列表会渲染全部DOM节点,数据量过万时页面卡顿、内存溢出。虚拟列表仅渲染可视区域DOM,滚动时动态销毁创建节点,百万级数据也可流畅滚动。
4.1 行业方案选型
-
Vue项目:vue-virtual-scroller、el-virtual-list
-
React项目:react-virtualized、react-window
4.2 适用场景
数据量≥1000条的告警列表、设备日志、历史数据列表,是物联网前端性能优化标配。
虚拟列表示例代码
<template>
<RecycleScroller
class="list-box"
:items="allAlarmData"
:item-size="60"
key-field="id"
>
<template #default="{ item }">
<div class="alarm-row">
<span>{{ item.alarmTime }}</span>
<span>{{ item.deviceName }}</span>
<span>{{ item.content }}</span>
</div>
</template>
</RecycleScroller>
</template>
<script setup>
import { RecycleScroller } from 'vue-virtual-scroller'
import { ref } from 'vue'
const allAlarmData = ref([])
</script>
4.3 通用开发规范
-
安全校验:前端仅视觉限制,权限、数据过滤后端二次校验
-
交互规范:无权限按钮置灰不隐藏,非法路由自动跳转首页
-
性能规范:小数据分页、大数据虚拟列表、海量图表数据后端降采样
-
容错规范:网络重试、空数据兜底、全局加载与报错提示
四、API对接与联调(物联网工程化核心)
物联网前端分为两大通信体系:HTTP/REST短连接(基础查询、历史数据、指令下发)、WebSocket/MQTT长连接(实时数据、设备状态、告警推送),配套Axios封装、跨域处理、全局异常拦截,适配Vue2/Vue3主流开发栈。
1. RESTful API规范与Axios封装
1.1 核心名词释义
-
API:前后端数据交互接口通道
-
RESTful:后端接口标准化设计规范,以资源为核心,通过HTTP方法区分操作
-
Axios:前端标准HTTP请求库,替代原生fetch,支持拦截器、超时、Promise封装
-
Token:登录身份凭证,每次请求携带,用于权限校验
-
拦截器:统一处理请求头、响应数据、全局异常
1.2 RESTful接口规范
HTTP方法语义(物联网通用)
|
GET |
查询资源(只读) |
获取设备列表、查询历史数据、查看告警记录 |
|
POST |
新增资源/下发瞬时指令 |
创建设备分组、下发设备开关指令、上传日志 |
|
PUT |
全量更新资源 |
修改设备名称、完整更新设备配置 |
|
PATCH |
局部更新资源 |
修改数据上报周期、更新联系人信息 |
|
DELETE |
删除资源 |
删除废弃设备、清空历史告警记录 |
URL设计规则
-
资源用名词复数:/devices 设备集合、/devices/1001 单设备
-
URL禁止携带动作,不用 /getDevice、/addDevice
-
分页、筛选通过query参数传递
-
大型平台添加版本控制:/api/v1/devices
HTTP状态码规范
-
200:请求成功(GET/PUT/PATCH)
-
201:新增资源成功(POST)
-
400:参数错误、数据非法
-
401:未登录、Token过期
-
403:权限不足
-
404:接口/资源不存在
-
500:后端服务异常、数据库故障
1.3 Axios工程化封装(物联网专用)
统一处理Token携带、超时、响应解析、全局报错,避免页面重复编写冗余逻辑。
// src/utils/request.js
import axios from 'axios'
const service = axios.create({
baseURL: '/api/v1', // 接口基础路径
timeout: 15000 // 物联网设备接口响应慢,超时15秒
})
// 请求拦截器:统一携带Token
service.interceptors.request.use(config => {
const token = localStorage.getItem('iot_token')
if(token) config.headers.Authorization = `Bearer ${token}`
return config
})
// 响应拦截器:统一解析数据、处理异常
service.interceptors.response.use(
res => res.data.data, // 剥离外层包装,直接返回业务数据
err => Promise.reject(err) // 统一抛出异常
)
export default service
2. MQTT / WebSocket 长连接前端接入
2.1 核心名词释义
-
短连接(HTTP):前端主动请求、用完断开,适合历史数据查询
-
长连接(WebSocket/MQTT):持续连通,服务端主动推送,适合实时数据
-
MQTT:物联网专用轻量级协议,低功耗、小流量,适配传感器、单片机设备
-
MQTT over WebSocket:浏览器唯一接入MQTT服务的方案
-
Topic:消息主题(消息通道),订阅指定主题接收对应设备数据
-
QoS:消息质量,0=实时数据流、1=告警消息不丢失
2.2 WebSocket原生接入
依靠onopen、onmessage、onclose、onerror四大生命周期,实现实时数据接收、断线重连、指令下发,适配常规IoT大屏实时推送场景。
2.3 MQTT over WebSocket工业级接入
海量传感器、低功耗设备场景首选,主流依赖paho-mqtt、mqtt.js库。
核心流程
-
创建MQTT客户端,连接ws/wss协议服务地址
-
携带平台账号密码登录鉴权
-
订阅设备数据、状态、告警Topic
-
监听message回调,解析JSON数据渲染页面
-
通过publish下发设备控制指令
2.4 长连接通用优化
-
自动重连:断网、服务重启3秒自动重试
-
30秒心跳保活,防止网关断开空闲连接
-
数据节流渲染,避免高频数据导致页面卡顿
-
页面销毁关闭连接,防止重复订阅、数据叠加
3. 跨域处理与代理配置(联调核心)
浏览器同源策略会拦截前后端跨域请求,开发/生产环境采用不同解决方案。
3.1 开发环境:Vue CLI Proxy代理
仅本地npm run serve生效,打包后失效,适配REST接口+MQTT长连接。
// vue.config.js
module.exports = {
devServer: {
proxy: {
// 代理普通HTTP接口
'/api': {
target: 'http://127.0.0.1:8090',
changeOrigin: true,
pathRewrite: { '^/api': '' }
},
// 代理MQTT WebSocket长连接
'/mqtt-ws': {
target: 'ws://127.0.0.1:8091/mqtt',
ws: true, // 开启WebSocket代理必备
changeOrigin: true
}
}
}
}
3.2 生产环境:CORS+Nginx反向代理
项目打包上线后,依靠后端CORS配置或Nginx反向代理解决跨域,企业级项目主流使用Nginx。
# Nginx线上配置
server {
listen 80;
server_name iot.admin.com;
root /server/iot/dist;
index index.html;
# 解决Vue单页刷新404
location / {
try_files $uri $uri/ /index.html;
}
# 转发API接口
location /api/ {
proxy_pass http://127.0.0.1:8090/;
}
# 转发MQTT长连接
location /mqtt-ws/ {
proxy_pass http://127.0.0.1:8091/mqtt;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
3.3 联调高频踩坑点
-
Proxy仅开发环境生效,打包后完全失效
-
WebSocket/MQTT代理必须配置ws:true,否则连接秒断
-
pathRewrite根据后端接口前缀灵活调整
-
线上禁止依赖前端代理,必须Nginx/后端CORS兜底
3.3 联调高频踩坑点(附URL报错解决方案)
-
Proxy仅开发环境生效,打包后完全失效,线上必须依靠Nginx反向代理或后端CORS配置解决跨域
-
WebSocket/MQTT代理必须配置ws:true参数,否则长连接会秒断、连接建立失败
-
pathRewrite根据后端接口前缀灵活调整,前缀匹配错误会直接触发URL路径报错
-
线上禁止依赖前端代理,必须Nginx/后端CORS兜底,规避生产环境接口不通问题
-
URL拼写报错专项解决(对应本地8090/8091端口报错):本地联调出现「URL拼写可能存在错误」报错,核心原因为URL尾部携带多余分号、换行符等非法字符,或端口路径拼接错误。开发时需严格清洗请求地址,剔除 ;、换行、空格等无效字符,MQTT长连接地址需保证为 ws://127.0.0.1:8091/mqtt 纯标准路径,无多余后缀符号,同时核对代理配置路径与后端服务端口完全一致。
4. 接口异常统一处理
4.1 异常分类
-
网络异常:401登录失效、403权限不足、404接口不存在、500服务报错、超时断网
-
业务异常:设备不存在、设备离线、参数超限、账号权限不足
-
长连接异常:连接失败、订阅权限不足
以上为本阶段物联网前端开发的完整学习笔记,内容涵盖可视化大屏、设备交互、数据告警、前后端联调等核心实战内容。笔记内容均为实战总结,若存在知识点疏漏、表述偏差或技术误区,欢迎大家指正交流。



