You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+Express服务端转义< >符号后显示异常的解决求助

解决Socket.io中HTML实体转义后显示异常的问题

嘿,我完全懂你碰到的这个困扰——这是个典型的双重转义坑,我之前做实时聊天项目时也踩过类似的雷!

问题根源分析

你现在的服务端代码是把已经是HTML实体的&lt;和&gt;又转义了一遍:

// 错误的转义:把 &lt; 变成 &amp;lt;
data.message = data.message.replace(/\&lt;/g,"&amp;lt;")
data.message = data.message.replace(/\&gt;/g,"&amp;gt;")

当用户发送<hello>时,浏览器其实会自动把原始的<>转成&lt;hello&gt;(如果你是从输入框拿到的内容,可能已经是实体了),但你又把&lt;转成&amp;lt;,最终客户端拿到的就是&amp;lt;hello&amp;gt;。浏览器渲染时,&amp;会被解析成&,所以就显示成&lt;hello&gt;,完全不是你想要的效果。

正确的解决方案

方案1:修正服务端转义逻辑(针对原始字符转义)

你需要转义的是原始的<和>字符,而不是它们的HTML实体形式。修改服务端代码如下:

socket.on('message', function(data) {
  // 转义原始的 < 和 > 为对应的HTML实体
  data.message = data.message.replace(/</g, "&lt;").replace(/>/g, "&gt;");
  io.in(socket.current_room).emit('message', {message: data.message, id: socket.id});
});

客户端代码可以保持你原来的写法,因为现在服务端返回的&lt;和&gt;会被浏览器正确解析为文本形式的<和>:

socket.on('message', function(msg) {
  output.innerHTML += `<div class="mymessage-container"><div class="mymessage"><p class="me">${msg.message}</p></div></div>`;
});

方案2:客户端用textContent插入文本(更安全,推荐)

如果你想彻底避免XSS风险,同时不用在服务端做转义,可以直接在客户端使用textContent来插入文本——它会自动帮你转义所有HTML特殊字符,不会解析任何标签:

socket.on('message', function(msg) {
  // 创建DOM元素,避免innerHTML的XSS风险
  const container = document.createElement('div');
  container.className = 'mymessage-container';

  const messageWrap = document.createElement('div');
  messageWrap.className = 'mymessage';

  const contentPara = document.createElement('p');
  contentPara.className = 'me';
  contentPara.textContent = msg.message; // 关键:用textContent而非innerHTML

  // 组装元素并添加到页面
  messageWrap.appendChild(contentPara);
  container.appendChild(messageWrap);
  output.appendChild(container);
});

这种方式下,服务端不需要做任何转义处理,直接转发用户输入的内容即可,既安全又省心。

总结

核心问题就是搞反了转义的对象:要转义的是原始的<>,而不是它们的HTML实体。两种方案都能解决你的问题,推荐方案2,因为它能有效防止XSS攻击,更适合聊天类应用。

内容的提问来源于stack exchange,提问作者iLiA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:52:56