news 2026/11/4 15:38:52

Liquid 模板前端框架集成实战:React 里安全渲染的五个要点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Liquid 模板前端框架集成实战:React 里安全渲染的五个要点

Liquid 模板前端框架集成实战:React 里安全渲染的五个要点

【免费下载链接】liquidLiquid markup language. Safe, customer facing template language for flexible web apps.项目地址: https://gitcode.com/gh_mirrors/li/liquid

运营想自己改首页文案,直接让业务方在后台编辑前端模板。这时候第一反应就该是:模板文本来自外部,怎么保证它不会变成注入漏洞?前端框架集成里这类"不可信模板"问题,通常用 Liquid 模板来解决。Liquid 不执行代码,只负责把文本和数据组合成结果,安全边界是清晰的。

场景对比:让非工程师写模板,两种做法差在哪

把模板交给工程师之外的角色,通常有两条路:

  • 用通用服务端引擎,模板本质上就是代码。用户改一行,轻则整个请求挂掉,重则在服务器上执行任意逻辑,风险不可控。
  • 用 Liquid,模板只是"标记 + 变量引用 + 过滤器",语法层面就是非 eval 的,用户提交的模板不会执行代码。同时编译和渲染是分离的:解析做一次,之后每次请求只传数据渲染,开销集中在解析这一步。

第一条路的问题是安全和性能都失控;第二条路把"能写什么"提前框死了,后面的配置才有意义。

装好 liquidjs 并跑通 React 里的第一个模板

先装依赖,一行命令:npm install liquidjs。引擎实例建一个就够了,放在模块顶层,不要在组件里反复 new。

import { Liquid } from 'liquidjs'; const engine = new Liquid(); function Banner({ template, data }) { const [html, setHtml] = useState(''); useEffect(() => { engine.parseAndRender(template, data).then(setHtml); }, [template, data]); return <div dangerouslySetInnerHTML={{ __html: html }} />; }

模板和 data 变了就重新渲染,结果写进 DOM。Vue 侧流程一致:在 mounted 或 data 的 watch 里调 parseAndRender,把结果赋给绑定 v-html 的变量即可。

上线前打开三道安全网:严格模式、环境隔离、资源限制

严格变量和过滤器。不配的话,模板里引用了数据里不存在的字段,渲染出来是空字符串,没人报错,用户只看到"内容丢了",排查很费劲。打开严格模式后,未定义的变量和过滤器会直接抛错,问题在第一现场就暴露。

const options = { strict_variables: true, strict_filters: true, resource_limits: { render_score_limit: 1000, render_length_limit: 10000, }, }; const engine = new Liquid(options);

环境隔离。多个业务场景共用一个引擎时,所有标签和过滤器是全局注册的。场景 A 注册了一个叫 price 的过滤器,场景 B 的同名逻辑就被覆盖了,而且这种覆盖不会有任何提示。用独立环境把每个场景的注册包起来:

const shopEnv = Liquid.Environment.build((env) => { env.registerTag('customTag', CustomTag); });

资源限制。上面的 resource_limits 就是这道网。不配的话,一个写坏了的深层 for 循环会把浏览器主线程占满,页面卡死。render_score_limit 和 render_length_limit 给渲染过程设了上限,超限直接中断,而不是等用户刷新。

模板变多之后:缓存解析结果,注册业务过滤器

parse 是贵的那一步,render 是便宜的那一步。模板文本没变的时候,没必要每次渲染都重新解析,用 Map 把编译结果存下来:

const cache = new Map(); function renderOnce(template, data) { if (!cache.has(template)) cache.set(template, engine.parse(template)); return cache.get(template).render(data); }

过滤器方面,把展示逻辑从模板里拿出去。比如价格格式化,注册一行engine.registerFilter('price', (v) => '$' + v.toFixed(2)),模板里就能写{{ product.price | price }},模板本身不掺任何计算逻辑。

两种最典型的模板:商品列表和登录态问候这么写

电商商品列表,循环交给模板,数据传一个数组,格式化交给过滤器:

<ul id="products"> {% for product in products %} <li>{{ product.name }}: {{ product.price | price }}</li> {% endfor %} </ul>

登录态的动态内容,判断写在模板里,数据只传 user 对象:{% if user.logged_in %}欢迎回来,{{ user.name }}!{% else %}请先登录{% endif %}。两种写法有个共同点:模板只描述"数据长这样时显示什么",不写取数逻辑,数据一律由外层传进来。

发布前对照这份踩坑清单

  • 在 useEffect 里重复 parse:模板没变也每次重新解析,白付编译开销,按上一节的缓存写法收掉。
  • data 更新后忘记重渲染:useEffect 的依赖数组漏了 data,接口返回了新数据但画面不动,是新手最常踩的坑。
  • 严格模式没开:未定义变量静默渲染成空,线上表现为"内容时好时坏",日志里却什么都没有。
  • 多引擎或多环境并存时,某一边漏注册了过滤器,渲染出来是空的,报错信息又不直观,排查要绕一圈。

一句话收束:模板是数据不是代码,把边界画清楚——语法边界、数据边界、资源边界,然后才谈得上让业务方动手。想继续深入,仓库里的 README.md 讲了语言的设计目标,lib/liquid/ 是核心源码目录(解析器、上下文都在里面),example/ 有一个可运行的示例服务,History.md 记录了版本演进。

【免费下载链接】liquidLiquid markup language. Safe, customer facing template language for flexible web apps.项目地址: https://gitcode.com/gh_mirrors/li/liquid

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 15:38:47

从静态对话到动态认知:Hermes Agent如何破解AI助手记忆与学习难题

从静态对话到动态认知&#xff1a;Hermes Agent如何破解AI助手记忆与学习难题 在当今AI助手泛滥的时代&#xff0c;大多数智能代理停留在"一问一答"的静态交互模式&#xff0c;缺乏持续学习和个性化适应的能力。用户面临的挑战是显而易见的&#xff1a;每次对话都是…

作者头像 李华
网站建设 2026/11/4 15:36:37

i.MX RT1180 双核 BSP 实战:从编译下载到 CM33 拉起 CM7 核间通信

i.MX RT1180 双核 BSP 实战&#xff1a;从编译下载到 CM33 拉起 CM7 核间通信 【免费下载链接】rt-thread RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/ 项目地址: https://gitcode.com/gh_mirrors/rt/rt-th…

作者头像 李华
网站建设 2026/11/4 15:34:13

Waydroid 3 步跑通:Linux 容器启动 Android

Waydroid 3 步跑通:Linux 容器启动 Android 【免费下载链接】waydroid Waydroid uses a container-based approach to boot a full Android system on a regular GNU/Linux system like Ubuntu. 项目地址: https://gitcode.com/gh_mirrors/wa/waydroid Waydroid 用容器在…

作者头像 李华
网站建设 2026/11/4 15:30:01

工业操作系统从预研到落地:实时性、可靠性工程实践与踩坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华