textContent 不能无条件替代 innerHTML:前者仅渲染纯文本、防 XSS,后者解析 HTML 结构;需根据是否需渲染标签来选择,不可信内容一律优先用 textContent。

WebSocket 收到消息后怎么安全插入 DOM
直接 innerHTML += msg.content 会引发 XSS 和 DOM 结构错乱,尤其当消息含 HTML 标签或未闭合标签时。必须先做转义或使用结构化方式插入。
- 用
textContent替代innerHTML渲染纯文本内容,完全规避 XSS - 若需保留简单格式(如换行、粗体),先用
escapeHtml()转义后再用innerHTML,不要信任任何后端字段 - 避免拼接字符串:不用
`,改用${msg.username}`document.createElement('div')+textContent组合 - 批量追加多条消息时,先创建
DocumentFragment,再一次性appendChild,减少重排
为什么用 template 标签比 innerHTML 更可靠
template 的 content 是只读 DocumentFragment,天然跳过解析和执行,不会触发脚本、加载图片或误渲染损坏结构——这对不可信的后台消息特别关键。
- 必须调用
tmpl.content.cloneNode(true),否则第二次appendChild会静默失败(内容已被移走) - 克隆后才能用
querySelector找子元素并填值,原始content上查不到节点 - 模板中不能依赖
onclick等内联事件,得手动addEventListener - IE 不支持
template,但可低成本降级:用script type="text/template"包裹,innerHTML读取后创建临时template
滚动到底部自动聚焦新消息的坑
用 container.scrollTop = container.scrollHeight 看似简单,但在消息高频到达时极易卡顿或失效——因为 DOM 尚未完成渲染,scrollHeight 取的是旧值。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 确保在所有消息节点已插入且布局完成后再滚动,推荐用
requestAnimationFrame延迟执行 - 如果容器用了
overflow: hidden或 flex 布局,scrollTop可能被忽略,需检查 computed style - 移动端 Safari 对频繁
scrollTop更新响应滞后,可加节流:只在最后一条消息插入后触发一次 - 不要监听
DOMNodeInserted(已废弃),改用MutationObserver监听新增子节点
服务端推送 JSON 结构该怎么设计才方便前端渲染
后端返回字段名不统一(比如 msg / message / content)、缺时间戳、没唯一 ID,会让前端遍历和去重变得脆弱。
- 强制约定字段:必含
id(字符串或数字)、content(纯文本)、timestamp(ISO 8601)、sender(非空字符串) - 避免嵌套对象传参,如
user: { name: "A" }→ 改为扁平sender_name: "A",减少前端解构成本 - 带类型标识:
{"type": "system", "content": "群已解散"},前端可按type分支处理样式和逻辑 - 首次连接时返回
last_seen_id,后续仅推送该 ID 之后的消息,避免重复或漏收
真正难的不是把字符串塞进页面,而是消息来了之后,DOM 是否还活着、滚动位置是否还在、重复消息有没有被过滤、用户正在输入时会不会被意外打断——这些边界情况,往往在压测或真实弱网下才暴露。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










