textarea的value赋值时出现

layui 的 textarea 本身不自动转义内容,但一旦你用 JavaScript 把带特殊字符的字符串赋值给它(比如 elem.value = userInput),或通过 laytpl 渲染、form.val() 设置值,就可能触发意外转义或解析异常——问题不在 textarea 标签,而在你「怎么把数据塞进去」。
textarea 的 value 赋值时为何出现
常见现象:后端返回 "<script>alert(1)</script>",前端用 form.val('form-filter', { content: data.content }) 设置到 textarea 后,里面显示的是 <script>alert(1)</script>。
原因在于 form.val() 内部调用了 layui.util.escape() 对所有字段值统一转义,哪怕目标是 textarea 这种天然支持原样显示的元素。
- 这不是 bug,是 form 模块为防 XSS 对「所有表单控件值」做的保守处理
-
textarea的value属性本该原样接收,但form.val()把它当普通文本一并转义了 - 直接操作 DOM 更安全:
document.querySelector('[name="content"]').value = data.content
laytpl 模板里渲染 textarea 内容要避开 {{ }} 默认转义
如果你用 laytpl 渲染整个表单 HTML(比如编辑页模板),写 <textarea name="desc">{{ d.desc }}</textarea>,那 d.desc 里的 、<code>& 会被自动转成 、<code>&,用户看到的就是源码而非原始符号。
- 改用
{{= d.desc }}—— 这是 laytpl 的「强制转义输出」语法,和{{ d.desc }}效果一样,但显式声明,不解决根本问题 - 真正要的是「不转义」:用
{{! d.desc }}(注意是叹号)—— laytpl 的原始输出语法,跳过所有转义 - 但必须确保
d.desc已由后端或 DOMPurify 过滤过,否则 XSS 风险直通 textarea
用户提交的 textarea 内容如何安全回显到页面其他位置
比如用户在 textarea 里写了 测试 & <b>加粗</b>,提交后你要在下方 div 里显示「预览」,这时不能直接 el.innerHTML = userInput。
- 纯文本展示(推荐):
el.textContent = userInput—— 安全、简单、无 XSS - 需保留简单格式(如换行、
<br>):el.innerHTML = layui.util.escape(userInput).replace(/\n/g, '<br>')
- 需渲染富文本(如含
<b></b>、<a></a>):必须用DOMPurify.sanitize(userInput),不能只靠escape() - 千万别用
userInput.replace(/, '/g, '>')这类手写正则——漏掉&就等于留后门
最易被忽略的一点:textarea 是少数几个「内容天然不参与 HTML 解析」的元素,但只要你把它卷进 form.val()、laytpl {{ }} 或 innerHTML 渲染链,它就立刻失去这个特权。安全边界不在标签本身,而在你选择哪条数据流转路径。











