【问题标题】:How can I access the browsers localStorage in Blazor?如何访问 Blazor 中的浏览器 localStorage?
【发布时间】:2018-09-17 04:39:39
【问题描述】:

我想支持 JWT,所以我需要保留令牌;有什么设施可以访问这个吗?还是我们现在应该注册我们自己的 javascript 函数来访问这个功能?

编辑:根据建议,我尝试将 JS 互操作用作:

<script>
    localStorage.setItem("key1", "key1data");
    Blazor.registerFunction("readStorage", (key) => {
        return localStorage.getItem(key);
    });
</script>
@if (jwtKey == null)
{
<div class="login-panel">
    <p>JWT not loaded</p>
</div>
}
else
{
<div class="login-panel">
    <p>@jwtKey</p>
</div>
}

@functions {
    public RenderFragment Body { get; set; }
    string jwtKey;

    protected override async Task OnInitAsync()
    {
        jwtKey = RegisteredFunction.Invoke<string>("readStorage", "key1");
        if (jwtKey == null)
        {
            jwtKey = "Unknown";
        }
    }
}

但这会导致诊断中出现 WASM 错误:

WASM: [Microsoft.AspNetCore.Blazor.Browser.Interop.JavaScriptException] 找不到名为“readStorage”的注册函数。黄蜂: 错误:找不到名为“readStorage”的注册函数。

仅供参考,这是在 Blazor VS 样板项目的 MainLayout.cshtml 中。

(如果合适,可以提出一个新问题;不过与这个问题有些相关)

【问题讨论】:

  • 我已经用按钮作为触发器对此进行了测试,并且可以正常工作。我猜脚本是在异步调用之后执行的。所以你应该在这个过程的早期注册你的函数

标签: c# asp.net-core blazor


【解决方案1】:

对于 0.1,您需要编写自己的 javascript 互操作。但我相信这是可行的,也许在 0.2 版本中。

或者(如果您不需要会话之间的存储)您可以编写自己的 DI 单例,就像这里所做的那样:https://github.com/aspnet/samples/blob/master/samples/aspnetcore/blazor/FlightFinder/FlightFinder.Client/Services/AppState.cs

编辑
有一个公开的 PR,所以确实应该很快就会出现:https://github.com/aspnet/Blazor/pull/205

编辑2 0.2 已经完成,但还没有本地存储。与此同时,我为此开发了一个包:BlazorExtensions也在nuget上

【讨论】:

  • 太棒了,谢谢 :) 我尝试按照您的建议使用现有的互操作,但它似乎不起作用? (更新问题以说明)
  • 啊,是的,解决了它。似乎应该有一种方法可以针对这种情况对操作进行序列化(即,如果用户登录,他们会得到一个面板与另一个面板)。以防 Blazor 团队的工作项目不足:)
  • 我要做的是在app.cshtml中注册我的javascript函数,就在router标签下面,你应该试试。
  • 不会改变我系统上的行为(仍然抛出);这似乎可能是对时间问题的一个补丁,以使其更有可能首先执行 javascript,但如果不能保证它会这样做很危险。真的,最干净的解决方案显然是while(true) { try { Invoke() } catch (JavaScriptException) { await Task.Delay(100); } } (/sarcasm)
【解决方案2】:

它可能会在默认情况下在 Blazor 中实现,但现在我正在使用: Nuget - BlazorStorage

【讨论】:

【解决方案3】:

如果其他人为此苦苦挣扎(截至 2018 年 6 月至 7 月): Steve Sanderson 在他的 NDC 会议视频中谈到了这个问题(本地存储): https://www.youtube.com/watch?v=JU-6pAxqAa4 从大约 45 分钟左右开始。

他为此使用了一个 nuget 包: https://github.com/cloudcrate/BlazorStorage 页面上的用法示例,这里不再赘述。

【讨论】:

    【解决方案4】:

    Microsoft 有自己的软件包 Microsoft.AspNetCore.ProtectedBrowserStorage 但目前还没有生产,它只适用于服务器端 blazor。

    如果你不想拥有第三方依赖,你可以通过JS interop轻松实现它。

    public class LocalStorage
    {
        private readonly IJSRuntime _jsRuntime;
    
        public LocalStorage(IJSRuntime jsRuntime)
        {
            _jsRuntime = jsRuntime;
        }
    
        public async Task SetAsync<T>(string key, T value)
        {
            string jsVal = null;
            if (value != null)
                jsVal = JsonSerializer.Serialize(value);
            await _jsRuntime.InvokeVoidAsync("localStorage.setItem", 
                new object[] { key, jsVal });
        }
        public async Task<T> GetAsync<T>(string key)
        {
            string val = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", key);
            if (val == null) return default;
            T result = JsonSerializer.Deserialize<T>(val);
            return result;
        }
        public async Task RemoveAsync(string key)
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
        }
        public async Task ClearAsync()
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.clear");
        }
    }
    

    用法:

    await _localStorage.SetAsync("Test", 42);
    var val = await _localStorage.GetAsync<int>("Test");
    await _localStorage.RemoveAsync("Test");
    await _localStorage.ClearAsync();
    

    【讨论】:

    • 这是一个很好的解决方案,但可以做得更健壮。 System.Text.Json 不能很好地处理匿名对象。使用启用了 TypeNameHandling 的 NewtonSoft.JsonConvert 可以获得更好的结果。此外,GetItem 确实是唯一需要 async/await 或需要类型参数的方法。 SetItem 可以只接受任何对象。 +1
    【解决方案5】:

    现在有一个名为 Blazor.Extensions.Storage 的包,它是一个精选扩展 https://github.com/BlazorExtensions/Storage

    【讨论】:

      猜你喜欢
      • 2019-07-05
      • 1970-01-01
      • 2021-08-07
      • 2023-02-09
      • 2020-02-24
      • 2018-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多