Hi @929Free,
您提到的 Routes.razor 和 App.razor 都不好,Routes.razor的现象你已经知道不满足您的需求。
App.razor中实现此功能,我理解的强制退出为关闭浏览器,因为生命周期的原因,我们无法简单的就能实现通过调用javascript代码进行实现,我们会遇到经典的错误讯息如下。
JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.
至于第三点你考虑的是一个通用的安全问题,如果非法用户确实要恶意破解我们也没有好的办法。所以从asp.net core 产品的角度我的建议是, 首先应用需要添加authentication的保护,所有的操作我们只允许授权用户进行操作。 ASP.NET Core 中的速率限制中间件可以帮助我们提高安全性。
回到您最初的问题,因为blazor是靠signalr进行通信的,所以我觉得在不干扰组件生命周期的情况下,使用signalr是最合适的。
创建自定义Signalr hub(也可以加上认证授权),然后你可以进行你注册码的校验逻辑,后端Signalr hub可以对发送的注册码信息进行校验, 然后发送websocket消息给前端。 这时候前端就可以直接使用window.close(); 方法,强制关闭当前页面。【具体的实现逻辑需要您自己去实现】,下面是部分的示例代码。
App.razor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="2168208.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet @rendermode="InteractiveServer"/>
</head>
<body>
<Routes @rendermode="InteractiveServer"/>
<script src="_framework/blazor.web.js" autostart="false"></script>
@* //测试的前端javascript 类库包,建议生产环境使用最新的 *@
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.0/signalr.min.js"></script>
<script>
// connect heartbeatHub
const connection = new signalR.HubConnectionBuilder()
.withUrl("/heartbeatHub")
.build();
connection.start().then(() => {
console.log("Connected to heartbeatHub");
// 强制退出应用,这里仅作为测试,你可以创建自己的逻辑验证注册码
// 前后端进行校验后, 通过signalr 客户端监听事件进行关闭当前窗口
// 此方法测试有效
//window.close();
setInterval(() => {
connection.invoke("SendHeartbeat")
.then(() => console.log("Heartbeat sent"))
.catch(err => console.error(err.toString()));
}, 5 * 60 * 1000); // Every 5 minutes will sent a Heartbeat
}).catch(err => console.error(err.toString()));
connection.on("HeartbeatReceived", (message) => {
console.log(`Server response: ${message}`);
});
connection.onclose(async () => {
console.log("Connection closed, retrying...");
await connection.start();
});
</script>
</body>
</html>
HeartbeatHub.cs
using Microsoft.AspNetCore.SignalR;
namespace _2168208
{
public class HeartbeatHub : Hub
{
public async Task SendHeartbeat()
{
Console.WriteLine($"Received heartbeat from {Context.ConnectionId} at {DateTime.UtcNow}");
await Clients.Caller.SendAsync("HeartbeatReceived", "pong");
}
}
}
Program.cs 注册
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
// Register HeartbeatHub
app.MapHub<HeartbeatHub>("/heartbeatHub");
app.Run();
你可以去掉注释,测试下,结果是刚启动就会关闭当前浏览器窗口。
//window.close();
如果答案是正确的解决方案,请点击“接受答案”并投赞成票。如果您对此答案有其他问题,请点击“评论”。
注意:如果您想接收此线程的相关电子邮件通知,请按照我们的 文档 中的步骤启用电子邮件通知。
Best Regards
Jason