如何在Thymeleaf的onClick方法中正确设置跳转链接?
我明白你遇到的问题了——从JSP转用Thymeleaf开发时,你给删除按钮加了确认对话框,但点击确定后跳转出错。核心原因是你直接在onclick的字符串里写了Thymeleaf的URL表达式@{...},但Thymeleaf不会解析字符串内部的这个表达式,导致传递给JS函数的是字面量文本(比如@{/deleteStudent/(id=${student.id})}),而不是真实的删除URL。
下面给你两种可行的解决方案:
方案1:使用Thymeleaf文本内联解析URL
Thymeleaf支持用|...|语法做文本内联,这样里面的URL表达式会被正确解析。修改你的删除按钮代码如下:
<tr th:each="student,iterStat : ${studentList}"> <td th:text="${student.id}"></td> <td th:text="${student.roll}"></td> <td th:text="${student.firstName}"></td> <td th:text="${student.lastName}"></td> <td th:text="${student.age}"></td> <td> <a href="#" th:onclick="|confirmRemoveQuestion('@{/deleteStudent(id=${student.id})}')|"> Delete </a> </td> </tr> <script> function confirmRemoveQuestion(link) { if (confirm("Are you sure you want to do this?")) { window.location.href = link; } } </script>
这里的th:onclick结合|...|会让Thymeleaf把@{/deleteStudent(id=${student.id})}解析成实际的URL(比如/deleteStudent?id=123),再传递给JS函数,这样点击确定后就能正确跳转了。我还简化了你的show_confirm函数,直接用原生的confirm方法即可,没必要额外封装。
方案2:用data属性存储URL(更推荐的前端实践)
这种方式把HTML和JS逻辑分离,更符合现代前端开发的规范,也避免了内联事件处理的麻烦:
<tr th:each="student,iterStat : ${studentList}"> <td th:text="${student.id}"></td> <td th:text="${student.roll}"></td> <td th:text="${student.firstName}"></td> <td th:text="${student.lastName}"></td> <td th:text="${student.age}"></td> <td> <a href="#" class="delete-btn" th:data-delete-url="@{/deleteStudent(id=${student.id})}"> Delete </a> </td> </tr> <script> // 给所有删除按钮绑定点击事件 document.querySelectorAll('.delete-btn').forEach(btn => { btn.addEventListener('click', function(e) { e.preventDefault(); // 阻止默认的#跳转行为 const deleteUrl = this.dataset.deleteUrl; if (confirm("Are you sure you want to delete this student?")) { window.location.href = deleteUrl; } }); }); </script>
这里我们用th:data-delete-url把解析后的删除URL存储在按钮的自定义data属性里,然后通过JS读取这个属性值,再触发确认和跳转逻辑。这种方式更清晰,也更容易维护。
另外提个小建议:按照REST规范,删除操作更适合用POST或DELETE请求,而不是GET请求(GET请求不应该用来修改服务器状态)。如果后续你想优化,可以把删除改成表单提交或者AJAX请求,但当前先解决确认对话框的跳转问题就可以了。
内容的提问来源于stack exchange,提问作者Avijit Barua

