Skip to content
Go back

小程序文章详情页如何渲染服务端富文本

资讯类产品的详情页往往来自一份富文本内容。Web 页面中可以将经过安全处理的 HTML 放入页面进行展示,但小程序的运行环境与浏览器 DOM 不同,不能简单假定任意 HTML、样式和交互都可以直接复用。

文章详情页真正要解决的是一条转换链路:服务端内容如何进入小程序节点体系,正文中的图片和图集如何继续保持可交互,以及遇到不支持的结构时如何可靠降级。

先限定内容能力而不是追求完整 HTML

资讯正文常见元素相对有限:

段落、换行、标题、加粗文本普通图片、图片说明、图集引用、列表、链接视频或其他扩展媒体

如果一开始目标就是还原浏览器的全部 HTML 能力,实现会很容易失控。更合理的方式是先定义文章协议支持的节点类型,再将原始内容转换到这个协议上:

const nodes = [  { type: "paragraph", children: [{ type: "text", value: "车辆外观..." }] },  { type: "image", src: "https://img.example.com/car.jpg", width: 750 },  {    type: "gallery",    images: [      "https://img.example.com/1.jpg",      "https://img.example.com/2.jpg"    ]  }];

页面不再承担解析任意字符串的责任,而是负责渲染有限且稳定的数据类型。

HTML 需要经过解析和转换

如果上游仍然提供 HTML,可以通过解析器生成语法树,再对白名单节点执行转换:

function transformNode(node) {  if (node.name === "p") {    return {      type: "paragraph",      children: transformChildren(node.children)    };  }  if (node.name === "img") {    return {      type: "image",      src: normalizeImageUrl(node.attribs.src),      alt: node.attribs.alt || ""    };  }  if (node.name === "strong") {    return {      type: "strong",      children: transformChildren(node.children)    };  }  return transformChildren(node.children || []);}

这里最重要的不是代码长短,而是白名单边界。脚本、未知内联样式和难以支持的标签不应直接进入渲染结果。对于不认识的容器结构,可以尽量保留内部文本,避免整段正文丢失。

图片不是普通文本节点

正文中的图片通常还需要承担额外交互:

在解析阶段可以同步收集图片列表:

function collectImages(nodes) {  return nodes    .filter(node => node.type === "image")    .map(node => node.src);}function previewImage(current, images) {  wx.previewImage({    current,    urls: images  });}

渲染一个图片节点时绑定当前地址和完整图集,正文中的普通插图就能够自然获得查看大图和左右切换能力。

图集应当成为独立内容节点

有些文章的图片本身是一组内容,例如车辆内饰细节或现场图集。它和正文中偶尔出现的一张配图不完全一样,往往需要展示数量、当前索引或一个明显的浏览入口。

因此图集不适合在模板里临时猜测,可以在内容协议中独立表示:

function ArticleNode({ node, articleImages }) {  switch (node.type) {    case "paragraph":      return <RichText nodes={node.children} />;    case "image":      return (        <Image          src={node.src}          onClick={() => previewImage(node.src, articleImages)}        />      );    case "gallery":      return <Gallery images={node.images} />;    default:      return null;  }}

这样后续对图集加入封面、页数或加载策略时,不会污染普通图片渲染逻辑。

转换放在哪里需要衡量

HTML 到节点协议的转换可以放在服务端,也可以放在小程序端。

服务端转换的优势是多个终端可共享内容处理结果,小程序首屏工作更少,也更容易统一内容安全规则。客户端转换便于快速调整展示策略,但会增加包体、计算成本和版本间结果差异。

对于内容类型稳定、访问量较大的资讯详情页,更倾向于让服务端输出适合终端消费的结构化结果,小程序保留少量展示适配和异常兜底。

详情页的质量取决于异常内容

真实文章中总会出现缺少尺寸的图片、失效链接、不支持的标签或内容数据不完整。详情页不能因为一张图解析失败就中断整篇文章渲染。

可以为每种节点准备降级策略:

未知文字容器 -> 保留纯文本图片加载失败 -> 显示失败占位,不影响后续段落空图集 -> 不展示模块不支持媒体 -> 展示可点击的来源链接或占位提示

资讯详情页看起来是内容展示,实际上包含内容协议、节点转换、图片交互和异常容错。把富文本先转换成受控的节点模型,页面才有能力持续扩展,而不会被任意 HTML 结构牵着走。


Share this post on: