如何使用 blazor 创建 cookie 客户端
Posted
技术标签:
【中文标题】如何使用 blazor 创建 cookie 客户端【英文标题】:How do I create a cookie client side using blazor 【发布时间】:2019-05-30 04:21:32 【问题描述】:我有一个登录页面,该页面向服务器发送了一堆数据,然后我想获取其中一些数据并使用客户端上的 Blazor 将其保存到 cookie 中。
所以首先我已经成功注入了 IHttpContextAccessor。现在在我的 Blazor 函数中,我有:
httpContextAccessor.HttpContext.Response.Cookies.Append("test", "ddd");
在调试中,当我点击上面的代码行时,它会出错:
“标头是只读的,响应已经开始。”
当然,我不会在 cookie 中保存带有“ddd”的“test”,我现在只是想获取一个 cookie 来保存。
【问题讨论】:
另一种方法是通过this Blazor library 使用LocalStorage
。 IMO,它是 Blazor 应用程序的更合适的客户端存储工具,因为每次请求都会发送 cookie,而本地存储是 Blazor 应用程序可用的数据,可以根据需要使用。
我们尽可能使用本地存储,但是对于这一点,我们与之交互的另一个软件会查找存储在 Cookie 中的信息。这个应用程序需要代表次要软件创建它,直到我们能够改变它。
【参考方案1】:
你必须使用 JS 互操作:
public async static Task WriteCookieAsync(string name, string value, int days)
var test = await JSRuntime.Current.InvokeAsync<object>("blazorExtensions.WriteCookie", name, value, days);
从 ASP.NET Core 3.0.0-preview3 ([Discussion] Microsoft.Interop.JSRuntime.Current has been removed) 开始,Current 属性不可用,所以使用以下代码:
var test = await JSRuntime.InvokeAsync<string>("blazorExtensions.WriteCookie", name, value, days);
别忘了在顶部注入 IJSRuntime:
@inject IJSRuntime JSRuntime
还有这个 JS:
window.blazorExtensions =
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=/";
【讨论】:
我知道现在还为时过早,但我祈祷每次我想做这样的小事情时不必总是使用 JS 互操作,这应该是一个开箱即用的功能。不过谢谢,这很有帮助! 我同意,最终这将由社区包提供。见这里:github.com/BlazorExtensions【参考方案2】:如果你想避免外部脚本依赖
await jsRuntime.InvokeVoidAsync("eval", $"document.cookie = \"cookieValue\"")
保留正确转义 cookie 值。
【讨论】:
【参考方案3】:您可以在<script>
标签中添加@Flores in_Host.cshtml
解释的javascript
。
<script>
window.blazorExtensions =
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=/";
</script>
【讨论】:
【参考方案4】:您可以在没有任何脚本的情况下使用这种方式: 首先定义这个服务:
using Microsoft.JSInterop;
namespace MyProject.Utils
public interface ICookie
public Task SetValue(string key, string value, int? days = null);
public Task<string> GetValue(string key, string def = "");
public class Cookie : ICookie
readonly IJSRuntime JSRuntime;
string expires = "";
public Cookie(IJSRuntime jsRuntime)
JSRuntime = jsRuntime;
ExpireDays = 300;
public async Task SetValue(string key, string value, int? days = null)
var curExp = (days != null) ? (days > 0 ? DateToUTC(days.Value) : "") : expires;
await SetCookie($"key=value; expires=curExp; path=/");
public async Task<string> GetValue(string key, string def = "")
var cValue = await GetCookie();
if (string.IsNullOrEmpty(cValue)) return def;
var vals = cValue.Split(';');
foreach (var val in vals)
if(!string.IsNullOrEmpty(val) && val.IndexOf('=') > 0)
if(val.Substring(1, val.IndexOf('=') - 1).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
return val.Substring(val.IndexOf('=') + 1);
return def;
private async Task SetCookie(string value)
await JSRuntime.InvokeVoidAsync("eval", $"document.cookie = \"value\"");
private async Task<string> GetCookie()
return await JSRuntime.InvokeAsync<string>("eval", $"document.cookie");
public int ExpireDays
set => expires = DateToUTC(value);
private static string DateToUTC(int days) => DateTime.Now.AddDays(days).ToUniversalTime().ToString("R");
您可以通过ExpireDays
设置默认过期时间,并在SetValue()
中将null
设置为days
以使用默认值或设置为0
用于会话或天数。
然后导入_import.razor
并添加到Program.cs
中的服务:
builder.Services.AddScoped<ICookie, Cookie>();
使用:
@inject ICookie cookie
...
await cookie.SetValue("mytest20", "Hello Mohsen!");
_message = await cookie.GetValue("mytest20");
尽情享受吧。
【讨论】:
if(val.Substring(1, val.IndexOf('=') - 1).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
应该是(val.Substring(0, val.IndexOf('=')).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
我认为以上是关于如何使用 blazor 创建 cookie 客户端的主要内容,如果未能解决你的问题,请参考以下文章
如何从服务器端 Blazor 应用程序中的 Blazor 组件调用 razor 页面而不导致页面刷新