Spring Boot应用中JavaScript Fetch无法发送HTTP请求问题排查
问题:表单提交后页面刷新,Fetch请求未正常执行
我在localhost:8080运行Spring服务器,通过PageController结合Thymeleaf返回登录页面。页面中的JavaScript代码尝试用Fetch API将表单数据以POST请求发送到/api/v1接口,但点击提交按钮后页面直接刷新,控制台仅能输出第一个控制点日志,后续日志无法显示,推测是默认表单提交行为未被正确阻止,导致Fetch请求无法完成。
相关代码
JavaScript代码
// select the submit button element from the DOM const submitBtn = document.getElementById("submit-btn"); console.log(1); // add an event listener to the button for the "submit" event submitBtn.addEventListener("submit", function(event) { // prevent the default form submission behavior event.preventDefault(); console.log(2); // define the data to be sent in the request body const userData = { username: document.getElementById("username").value, email: document.getElementById("emailf").value, schoolNumber: document.getElementById("school-n").value, dob: new Date(document.getElementById("dob").value).toISOString().split('T')[0] }; console.log(JSON.stringify(userData) + " 3"); // send the POST request fetch('http://localhost:8080/api/v1', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(userData) }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } // handle successful response }) .catch(error => { console.error('There was a problem with the fetch operation:', error); }); });
Thymeleaf页面代码
<!DOCTYPE html > <html lang="en" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Welcome to The Community</title> </head> <body> <form id="form-m"> <label for="username"></label><input type="text" id="username" value="tell me thy username"> <label for="emailf"></label><input type="email" id="emailf" value="yourmail@example.org"> <label for="school-n"></label><input type="number" id="school-n" value="000"> <label for="dob"></label><input type="date" id="dob" value="yyyy-mm-dd"> <button type="submit" id="submit-btn">submit</button> </form> <script type="text/javascript" th:src="@{/main.js}"></script> </body> </html>
PageController代码
@Controller //PageController.java public class PageController { @GetMapping("/login") public String loadLogin(Model m) { m.addAttribute("name","sex"); return "login"; } }
UserController代码
@PostMapping //default mapping for api/v1, UserController.java public void saveNewUser(@RequestBody UserSM u) { userService.saveNewUser(u); }
问题原因及解决方案
核心问题
你给按钮绑定了submit事件,但按钮本身没有submit事件,submit事件属于<form>元素。点击提交按钮时,浏览器会触发表单的默认submit行为(页面刷新),而你的按钮事件根本没触发,导致event.preventDefault()未执行,后续日志和Fetch请求都没机会运行。
修复方案
将事件监听器从按钮切换到表单上,监听表单的submit事件,即可正确阻止默认行为:
修改后的JavaScript代码:
// 选择表单元素而非按钮 const form = document.getElementById("form-m"); console.log(1); // 监听表单的submit事件 form.addEventListener("submit", function(event) { // 阻止默认表单提交行为 event.preventDefault(); console.log(2); // 收集表单数据 const userData = { username: document.getElementById("username").value, email: document.getElementById("emailf").value, schoolNumber: document.getElementById("school-n").value, dob: new Date(document.getElementById("dob").value).toISOString().split('T')[0] }; console.log(JSON.stringify(userData) + " 3"); // 发送POST请求 fetch('http://localhost:8080/api/v1', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(userData) }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } // 添加请求成功后的处理逻辑,比如提示用户 console.log("请求成功"); }) .catch(error => { console.error('Fetch请求出错:', error); }); });
额外提示
- 监听表单
submit事件比监听按钮click更稳妥,因为用户还可以通过回车键提交表单,此时按钮click事件不会触发,但表单submit事件依然会触发。 - 需确保UserController的
@PostMapping指定正确路径,当前代码未指定路径,需修改为@PostMapping("/api/v1"),否则会出现404错误。
内容的提问来源于stack exchange,提问作者Ozan Güneş Gençay
相关产品推荐
相关产品推荐

