Skip to content

12.3 JavaScript内联

JavaScript内联是Thymeleaf专为 <script> 标签设计的内联机制,能让你在 HTML 模板的 JS 代码块中无缝嵌入 Thymeleaf 表达式。

与文本内联类似,它本质上是将 <script> 内容按「JAVASCRIPT 模板模式」处理,因此所有文本模板模式的强大功能(详见下一章)都可以使用。不过,在本节中,我们将重点介绍如何使用它来将 Thymeleaf 表达式的输出添加到我们的 JavaScript 代码块中。

必须给 <script> 标签添加 th:inline="javascript" 显式激活该模式,之后就能在 JS 代码中使用 [[...]]/[(...)] 嵌入表达式:

html
<script th:inline="javascript">
    ...
    // 嵌入 Thymeleaf 表达式,生成 JS 变量
    var username = [[${session.user.name}]];
    ...
</script>

这将生成:

html
<script th:inline="javascript">
    ...
    // 嵌入 Thymeleaf 表达式,生成 JS 变量
    var username = "Sebastian \"Fruity\" Applejuice";
    ...
</script>
  • 字符串类型:自动包裹双引号,并转义内部的特殊字符(如 " 转义为 \");
  • 数字/布尔类型:直接输出值,不包裹引号,符合 JS 字面量规则。

上述代码中有两个要点需要注意:

首先,JavaScript 内联不仅会输出所需的文本,还会用引号将其括起来并对内容进行 JavaScript 转义,从而确保表达式的结果以格式良好的 JavaScript 字面量形式输出。

其次,这种情况的发生是因为我们将 ${session.user.name} 表达式作为转义内容输出,即使用了双括号表达式:[[${session.user.name}]]。如果我们改为使用非转义输出,例如:

html
<script th:inline="javascript">
    ...
    var username = [(${session.user.name})];
    ...
</script>

结果就像这样:

html
<script th:inline="javascript">
    ...
    var username = Sebastian "Fruity" Applejuice;
    ...
</script>

这将生成格式错误的 JavaScript 代码。但如果我们希望通过拼接内联表达式的方式来动态构建脚本的某些部分,输出非转义内容可能正是我们所需要的,所以掌握这个工具很有必要。

转义 vs 不转义:[[...]] vs [(...)]

1. 转义内联([[...]],推荐)

  • 行为:自动适配 JS 语法(加引号、转义特殊字符),生成合法的 JS 字面量;
  • 示例:
    html
    <script th:inline="javascript">
        var username = [[${session.user.name}]]; // 正确:带引号+转义
    </script>
  • 结果:var username = "Sebastian \"Fruity\" Applejuice";(合法 JS)。

2. 不转义内联([(...)],慎用)

  • 行为:直接输出表达式结果,不添加引号、不转义;
  • 示例:
    html
    <script th:inline="javascript">
        var username = [(${session.user.name})]; // 错误:无引号+未转义
    </script>
  • 结果:var username = Sebastian "Fruity" Applejuice;(非法 JS,会报错);
  • 适用场景:仅当你需要拼接 JS 代码片段(如动态生成函数体、语句)时使用,且必须确保内容是安全的合法 JS 代码。

重要规则

  1. 显式激活:必须添加 th:inline="javascript",否则 [[...]] 会被当作普通文本,导致 JS 语法错误;
  2. 原型友好性:静态预览时,<script> 内会显示 [[${session.user.name}]] 表达式,而非真实值,若需原型预览,可结合仅原型注释块:
    html
    <script>
        <!--/*/ <![CDATA[/*/-->
        var username = [[${session.user.name}]];
        <!--/*/ ]]> /*/-->
        // 静态预览时执行的备用代码
        var username = "Sebastian";
    </script>
  3. 安全性[[...]] 自动转义,能避免因用户输入的特殊字符(如 "\)导致的 JS 语法错误,是默认推荐用法;
  4. 作用域:仅作用于当前 <script> 标签内,不影响其他标签。

典型使用场景

  • 从后端传递用户信息、配置参数到前端 JS;
  • 动态生成 JS 逻辑(如根据后端权限控制前端按钮是否可用);
  • 传递国际化文本到前端(如 var tip = [[#{user.welcome}]];)。

总结

  1. JS 内联需通过 th:inline="javascript" 显式激活,核心价值是自动适配 JS 语法生成合法字面量;
  2. [[...]] 是推荐用法,自动加引号、转义特殊字符,保证 JS 语法合法;
  3. [(...)] 仅用于拼接 JS 代码片段,需确保内容安全合法,否则易导致语法错误;
  4. 需注意静态原型预览的问题,可通过注释块折中处理。