javascript - Blazor Webassembly JS 互操作 - “Microsoft.JSInterop.JSException:在‘窗口’中找不到‘WriteCookie’。”
问题描述
我正在尝试使用 JS Interop在客户端浏览器上存储 cookie 。
但是,我遇到了一个持续性错误,这个答案无助于缓解,而且我在网上找不到任何可行的解决方案。
我的 Index.razor 文件中有以下代码:
@page "/"
@using Blazored.LocalStorage
@inject HttpClient Http
@inject Blazored.LocalStorage.ISyncLocalStorageService localStorage
@inject IJSRuntime JSRuntime
@test
@code{
private string test { get; set; }
protected override async Task OnInitializedAsync()
{
try
{
await JSRuntime.InvokeAsync<bool>("methods.WriteCookie", "test cookie", "test cookie value", 2);
}catch(Exception e)
{
test = e.ToString();
}
}
}
我的 index.html 文件中有以下代码,位于 wwwroot 文件夹中:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>OptionalyticsFrontend</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss"></a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script src="optionalyticsExtensions.js"></script>
</body>
</html>
我的 optionalyticsExtensions.js 文件中有以下代码:
window.methods = {
WriteCookie: function(name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
}
else {
expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
return true;
}
}
这是我的 wwwroot 文件结构;index.html 定位 optionalyticsExtensions.js 应该没有问题:
然而,我一直收到这个错误:
Microsoft.JSInterop.JSException: Could not find 'methods' in 'window'.
Error: Could not find 'methods' in 'window'.
at https://localhost:44375/_framework/blazor.webassembly.js:1:9130
at Array.forEach (<anonymous>)
at p (https://localhost:44375/_framework/blazor.webassembly.js:1:9090)
at https://localhost:44375/_framework/blazor.webassembly.js:1:9800
at new Promise (<anonymous>)
at Object.beginInvokeJSFromDotNet (https://localhost:44375/_framework/blazor.webassembly.js:1:9773)
at _mono_wasm_invoke_js_marshalled (https://localhost:44375/_framework/wasm/dotnet.3.2.0.js:1:171294)
at do_icall (<anonymous>:wasm-function[6049]:0x10f8b1)
at do_icall_wrapper (<anonymous>:wasm-function[1896]:0x50b6a)
at interp_exec_method (<anonymous>:wasm-function[1120]:0x2588e)
at System.Threading.Tasks.ValueTask`1[TResult].get_Result () <0x2d9e7c8 + 0x00034> in <filename unknown>:0
at OptionalyticsFrontend.Client.Pages.Index.OnInitializedAsync () [0x0004c] in C:\Users\codef\source\repos\OptionalyticsFrontend\OptionalyticsFrontend\Client\Pages\Index.razor:24
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () <0x2baa8e8 + 0x0013a> in <filename unknown>:0
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask (System.Threading.Tasks.Task taskToHandle) <0x2d167d0 + 0x000b6> in <filename unknown>:0
我试过了:
- 将 JS 类/函数命名为其他名称
- 直接在 index.html 中编写脚本,而不是引用 .js 文件
- 编写一个简单的 JS 函数,它只接受 1 个参数并将其写入控制台,而不是这个 cookie 函数
- 摆脱 Index.razor 中的 try/catch 语句,以防万一搞砸了
- 更改 JSRuntime.InvokeAsync 调用的类型
- 更改 JS 函数返回的内容
似乎没有任何效果。
这里有什么问题?
解决方案
如果您使用此 cookie 进行任何类型的身份验证,您将不希望将它们存储在客户端中。这些 cookie 不安全。在用户进行身份验证后,您需要从您的服务器设置一个 HTTPOnly cookie。
HTTPOnly cookie 不允许客户端(以及任何扩展或其他第三方)查看或修改它,客户端基本上不会知道它的存在。然后,您可以将它包含在您将来发出的任何 API 请求的标头中,允许后端在继续之前验证您的令牌。
推荐阅读
- docker - 从容器内部构建和推送 docker 映像
- python - Python Dash Basic Auth - 在应用程序中获取用户名
- php - PHP 是否支持使用 HTTP/2 协议创建流上下文?
- java - Intellij idea spring boot 启动器:taglibs 未在 freemarker 中加载
- model-view-controller - 调用 AJAX MVC DNN
- android - 为什么我的 toast 可以在这么多不同的环境下工作?
- angular - 如何将角度组件连接到对话框组件?
- python - 从 Python 运行需要用户输入的 shell 脚本
- javascript - 使课程单独工作
- python-3.6 - 使用函数将数据解析为时间(Python)