如何在 Blazor 中访问浏览器 localStorage?
How can I access the browsers localStorage in Blazor?
我想支持 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]
Could not find registered function with name 'readStorage'. WASM:
Error: Could not find registered function with name 'readStorage'.
仅供参考,这在 Blazor VS 样板项目的 MainLayout.cshtml 中。
(如果合适可以提出一个新问题;虽然与这个问题有些相关)
对于 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 中实现,但现在我正在使用:
Nuget - BlazorStorage
以防其他人为此苦苦挣扎(截至 juni-july 2018 年):
Steve Sanderson 在他的 NDC 会议视频中解决了这个问题(本地存储):
https://www.youtube.com/watch?v=JU-6pAxqAa4
从大约第 45 分钟开始。
他为此使用了一个 nuget 包:
https://github.com/cloudcrate/BlazorStorage
页面上有使用示例,此处不再赘述。
现在有一个名为 Blazor.Extensions.Storage 的软件包,它是一个精心策划的扩展
https://github.com/BlazorExtensions/Storage
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();
我想支持 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] Could not find registered function with name 'readStorage'. WASM: Error: Could not find registered function with name 'readStorage'.
仅供参考,这在 Blazor VS 样板项目的 MainLayout.cshtml 中。
(如果合适可以提出一个新问题;虽然与这个问题有些相关)
对于 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 中实现,但现在我正在使用: Nuget - BlazorStorage
以防其他人为此苦苦挣扎(截至 juni-july 2018 年): Steve Sanderson 在他的 NDC 会议视频中解决了这个问题(本地存储): https://www.youtube.com/watch?v=JU-6pAxqAa4 从大约第 45 分钟开始。
他为此使用了一个 nuget 包: https://github.com/cloudcrate/BlazorStorage 页面上有使用示例,此处不再赘述。
现在有一个名为 Blazor.Extensions.Storage 的软件包,它是一个精心策划的扩展 https://github.com/BlazorExtensions/Storage
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();