如何在用户关闭页面时触发IndexModel的事件?(Razor+JS+C#)
解决关闭浏览器标签页触发后端事件的问题
问题根源
原代码用fetch异步请求配合beforeunload事件,页面关闭时浏览器会优先完成卸载,直接终止未完成的异步请求,导致后端收不到触发信号。而Navigator.sendBeacon()是浏览器专为页面卸载场景设计的API,会把请求放入后台队列,保证在页面关闭前完成发送。
修改后的前端代码
function sendFieldData() { var email = document.getElementById('EmailComprador').value; var telefone = document.getElementById('TelefoneComprador2').value; var nome = document.getElementById('NomeComprador2').value; if (email) { // 用FormData封装数据,兼容防伪造令牌和sendBeacon的参数要求 const formData = new FormData(); formData.append('CustomerEmail', email); formData.append('CustomerName', nome); formData.append('CustomerPhone', telefone); formData.append('__RequestVerificationToken', document.querySelector('input[name="__RequestVerificationToken"]').value); const url = `${window.location.pathname}?handler=SaveAbandonedCart`; // 发送请求,浏览器会保证请求完成 navigator.sendBeacon(url, formData); } } // 监听unload事件,页面卸载时触发 window.addEventListener('unload', function () { sendFieldData(); });
后端IndexModel适配代码
确保后端能正确接收FormData格式的请求:
public class IndexModel : PageModel { // 其他业务代码... public async Task<IActionResult> OnPostSaveAbandonedCartAsync(CustomerData customerData) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // 执行废弃购物车的保存逻辑,比如写入数据库 // ... return new JsonResult(new { success = true }); } // 定义接收数据的模型类 public class CustomerData { public string CustomerEmail { get; set; } public string CustomerName { get; set; } public string CustomerPhone { get; set; } } }
关键注意事项
- 防伪造令牌:确保页面中存在
__RequestVerificationToken输入框(可通过@Html.AntiForgeryToken()手动生成),否则后端会拒绝请求。 - 测试验证:部分浏览器在localhost环境下可能限制
sendBeacon,建议在生产环境或用代理工具测试;调试时打开浏览器控制台的「Preserve log」选项,可查看请求是否成功发送。 - 事件选择:用
unload而非beforeunload,后者主要用于提示用户确认离开,unload是页面实际卸载时触发,更适配该场景。
内容的提问来源于stack exchange,提问作者ChessDev
相关产品推荐
相关产品推荐

