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

Play Framework动态生成HTML链接问题:HTML代码显示而非图标

这个问题我之前也碰到过,本质是Play的模板引擎默认会转义HTML内容来防XSS,导致你的链接和图标代码被当成纯文本显示了。下面是具体的解决办法:

问题原因

Play Framework的Twirl模板引擎默认会对所有输出的字符串进行HTML转义(把<转成&lt;,>转成&gt;等),目的是防止XSS攻击。所以当你的getAuthor函数返回包含<a>、<img>标签的字符串时,模板会把这些标签转义成纯文本,浏览器就直接显示源码了。

解决方案

要让模板渲染HTML而不是转义它,你有两种常用方法:

方法1:让函数直接返回Html类型

Play提供了play.twirl.api.Html类,用来标记不需要转义的HTML内容。修改你的getAuthor函数,返回Html而不是普通String:

Scala示例

import play.twirl.api.Html
import play.twirl.api.HtmlFormat

def getAuthor(authors: List[String]): Html = authors match {
  case Nil => Html("")
  // 对单个作者名进行转义,防止XSS
  case single :: Nil => HtmlFormat.escape(single)
  case first :: rest =>
    // 先转义第一个作者名,再拼接HTML标签
    val escapedFirst = HtmlFormat.escape(first)
    Html(s"$escapedFirst <a href='/authors'><img src='/images/more.png' alt='查看更多作者'></a>")
}

然后在模板里直接调用:

@getAuthor(authorsList)

Java示例

import play.twirl.api.Html;
import play.twirl.api.HtmlFormat;

public static Html getAuthor(List<String> authors) {
    if (authors.isEmpty()) {
        return Html.apply("");
    } else if (authors.size() == 1) {
        // 转义作者名
        return HtmlFormat.escape(authors.get(0));
    } else {
        String firstAuthor = HtmlFormat.escape(authors.get(0)).toString();
        String html = firstAuthor + " <a href='/authors'><img src='/images/more.png' alt='查看更多作者'></a>";
        return Html.apply(html);
    }
}

模板中调用:

@controllers.YourController.getAuthor(authorsList)

方法2:在模板中用@Html()包裹返回值

如果你的函数必须返回String,可以在模板里把返回的字符串转换成Html对象,告诉模板不要转义:

@Html(getAuthor(authorsList))

⚠️ 重要提醒:如果authors列表中的内容来自用户输入,一定要先对作者名进行转义,避免XSS攻击。比如在函数里先用HtmlFormat.escape()处理每个作者名,再拼接HTML标签。

额外注意事项

永远不要直接把未转义的用户输入拼接到HTML中!如果有人输入类似<script>alert('XSS')</script>的作者名,直接渲染会导致恶意脚本执行。所以一定要用HtmlFormat.escape()处理用户提供的内容,再安全地拼接HTML标签。

内容的提问来源于stack exchange,提问作者A.G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:41:57