spring-boot - 当呈现为 html-text 时,Thymeleaf 模板中不处理内联 javascript
问题描述
我有一个构建报告的小型 SpringBoot 应用程序,我想通过电子邮件发送此报告。为了构建报告,我使用 Thymeleaf。为了构建图表,我使用了 google-charts,我将其渲染并插入为图像。
我用来在页面上显示报告和呈现电子邮件内容的模板是相同的:
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Report Generator</title>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
<!-- Bootstrap core CSS -->
<link href="../static/css/bootstrap.css" rel="stylesheet" th:href="@{css/bootstrap.css}"/>
</head>
<body class="d-flex h-100 text-center">
<div class="container-fluid">
<div class="p-4 p-md-5 mb-4">
<h1>Report Generator</h1>
<div>
<div class="table-responsive">
<table class="table table-striped table-sm text-center" style="font-size:1.7rem">
<thead>
<tr>
<th>Test plan</th>
<th>Name</th>
<th>Pass</th>
<th>Failed</th>
</tr>
</thead>
<tr th:each="data: ${allData}">
<td><a th:href="@{'https://jira.com/browse/' + ${data.testPlanId}}"
th:text="${data.testPlanId}"/></td>
<td th:text="${data.testExecutions[0].summary}"></td>
<td th:text="${data.testExecutions[0].testCaseResults.get('PASS')}"></td>
<td th:text="${data.testExecutions[0].testCaseResults.get('FAIL')} + ${allData[0].testExecutions[0].testCaseResults.get('NEW')}"></td>
</tr>
</table>
</div>
</div>
</div>
<div class="row mb-2">
<div class="col-md-12" th:each="data,stat:${allData}">
<div class="col-md-12">
<h3 th:text="${data.testExecutions[0].summary} +' ('+${data.testPlanId}+')'"/>
<div th:id="'chart_div'+${stat.index}" class="w-100 mw-100 p-3"></div>
</div>
</div>
<script th:inline="javascript">
var testExecutionData = /*[[${testExecutionData}]]*/'noValue';
var allData = /*[[${allData}]]*/'noValue';
$(document).ready(function() {
google.charts.load('current', {
packages : [ 'corechart', 'bar' ]
});
google.charts.setOnLoadCallback(drawColumnChart);
});
function drawColumnChart() {
for (i = 0; i < allData.length; i++) {
var data = prepareData(allData[i].testExecutions);
var options = {
colors: ['#06a10f', '#cc0808', '#ec8f6e', '#f3b49f', '#f6c7b6'],
annotations: {
alwaysOutside: true,
textStyle: {
fontSize: 14,
color: '#000',
auraColor: 'none'
}
}
};
var chartObj = document.getElementById('chart_div'+i);
var chart = new google.visualization.ColumnChart(chartObj);
google.visualization.events.addListener(chart, 'ready', function () {
chartObj.innerHTML = '<img src="' + chart.getImageURI() + '">';
});
chart.draw(data, options);
}
}
function prepareData(data){
var chartData = new google.visualization.DataTable();
chartData.addColumn('string', 'Test Execution');
chartData.addColumn('number', 'Passed');
chartData.addColumn({type: 'string', role: 'annotation'});
chartData.addColumn('number', 'Failed');
chartData.addColumn({type: 'string', role: 'annotation'});
chartData.addColumn('number', 'New');
chartData.addColumn({type: 'string', role: 'annotation'});
var size = (data.length < 5) ? data.length : 5;
for(var i=0; i<size; i++){
chartData.addRow([testExecutionData[i].key,
data[i].testCaseResults.PASS,
data[i].testCaseResults.PASS.toString(),
data[i].testCaseResults.FAIL,
data[i].testCaseResults.FAIL.toString(),
data[i].testCaseResults.NEW,
data[i].testCaseResults.NEW.toString()
]);
}
return chartData;
}
</script>
</div>
</div>
</body>
</html>
报告按预期成功呈现并显示在页面上,但是当我呈现电子邮件(不是插入的图表的图像)时未触发 inline-js。我像这样处理电子邮件的模板:
public void sendMessageUsingThymeleafTemplate(
String to, String subject, Map<String, Object> templateModel)
throws MessagingException {
Context thymeleafContext = new Context();
thymeleafContext.setVariables(templateModel);
String htmlBody = thymeleafTemplateEngine.process("report.html", thymeleafContext);
sendHtmlMessage(to, subject, htmlBody);
}
为什么 Thymeleaf 在呈现页面和将其呈现为 html-text 时对内联脚本的行为不同?
解决方案
我在浏览器中打开了 thymeleafTemplateEngine 为我呈现的 html,它显示了所有图表。显然,处理 javascript 而不是 Thymeleaf 是浏览器的工作。我需要找到一种方法在发送电子邮件之前对其进行预处理,以便像在浏览器中一样插入所有这些图像
<div id="chart_div0" class="w-100 mw-100 p-3"><img src="data:image/png;base64,iVBvx...">
推荐阅读
- sql - 如何在 postgres 表列中添加节点作为更新
- python - socket.gaierror: [Errno 11001] getaddrinfo 在尝试连接到 mqtt 代理时失败
- c# - 设置跟踪时间值的数据类型
- amazon-web-services - 无效的模板属性或属性 [Vpcname]
- graphql - HotChocolate、MongoDB 以及如何将其与 DTO 一起使用
- c# - 如何在不阻塞 main 中的其他方法的情况下运行后台 Quartz 进程
- mysql - 尝试将.NET网站部署到Amazon EC2时,如何修复用户'myusername@localhost'(使用密码:是)的mysql访问被拒绝?
- python - 从 pandas python 写入 csv 时,有没有办法删除空单元格(空单元格的逗号)?
- javascript - 无法对未安装的组件执行 React 状态更新。请帮帮我
- javascript - 在第二次点击而不是第一次点击时设置状态