【问题标题】:Blazor Webassembly JS Interop - "Microsoft.JSInterop.JSException: Could not find 'WriteCookie' in 'window'."Blazor Webassembly JS 互操作 - “Microsoft.JSInterop.JSException:在‘窗口’中找不到‘WriteCookie’。”
【发布时间】:2021-02-01 01:03:53
【问题描述】:

我正在尝试在客户端浏览器上存储一个 cookie,using a JS Interop

然而,我遇到了一个持续性错误,this answer 无助于缓解,而且我在网上找不到任何可行的解决方案。

我的 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 函数返回的内容

似乎没有任何效果。

这里有什么问题?

【问题讨论】:

  • 我在想你的 window.methods 只是在你运行脚本时没有定义。该错误看起来类似于基本的“x 未定义”
  • @Rohan 我尝试将其绑定到按钮而不是组件初始化,但它仍然给了我同样的错误。虽然根据我们的谈话,我可能会转向使用 httponly cookie,而不是尝试为任何东西设置客户端 cookie。
  • 很好奇它仍然没有运行,但是是的,我认为在意识到 cookie 用于身份验证后这不是问题。无论如何,我已经将我关于重新构建您的身份验证流程的建议放入了答案中。

标签: javascript c# blazor webassembly


【解决方案1】:

如果您将此 cookie 用于任何类型的身份验证,您将不希望将它们存储在客户端中。这些 cookie 不安全。用户通过身份验证后,您需要从服务器设置 HTTPOnly cookie。

HTTPOnly cookie 不允许客户端(以及任何扩展或其他第三方)查看或修改它,客户端基本上不会知道它的存在。然后,您可以将它包含在您将来发出的任何 API 请求的标头中,允许后端在继续之前验证您的令牌。

【讨论】:

    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 2021-09-22
    • 2021-03-03
    • 2021-12-07
    • 2020-08-14
    • 1970-01-01
    • 2022-08-10
    • 1970-01-01
    相关资源
    最近更新 更多