如何使用 blazor 创建 cookie 客户端
How do I create a cookie client side using blazor
我有一个登录页面,服务器会获取大量数据,然后我想获取其中一些数据并使用客户端上的 Blazor 将其保存到 cookie 中。
首先,我已经成功注入了 IHttpContextAccessor。现在在我的 Blazor 函数中我有:
httpContextAccessor.HttpContext.Response.Cookies.Append("test", "ddd");
在调试中,当我点击上面的代码行时出现错误:
"Headers are read-only, response has already started."
当然我不会在 cookie 中保存 "test" 和 "ddd",我只是想获取一个 cookie 来保存。
您将不得不使用 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=/";
}
}
您可以在Host.cshtml
和<script>
标签中添加@Flores解释的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>
如果你想避免外部脚本依赖
await jsRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{cookieValue}\"")
保留以正确转义 cookie 值。
不用脚本也可以这样使用:
首先定义这个服务:
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");
尽情享受吧。
借助 MohsenB provided. I have created a NuGet 为其打包的代码片段。
NuGet 安装:
Install-Package AltairCA.Blazor.WebAssembly.Cookie
Program.cs
builder.Services.AddAltairCACookieService(options =>
{
options.DefaultExpire = TimeSpan.FromMinutes(15);
});
使用示例
注入服务
@inject IAltairCABlazorCookieUtil _cookieUtil;
示例 1
await _cookieUtil.SetValueAsync("cookieName", "value");
我有一个登录页面,服务器会获取大量数据,然后我想获取其中一些数据并使用客户端上的 Blazor 将其保存到 cookie 中。
首先,我已经成功注入了 IHttpContextAccessor。现在在我的 Blazor 函数中我有:
httpContextAccessor.HttpContext.Response.Cookies.Append("test", "ddd");
在调试中,当我点击上面的代码行时出现错误:
"Headers are read-only, response has already started."
当然我不会在 cookie 中保存 "test" 和 "ddd",我只是想获取一个 cookie 来保存。
您将不得不使用 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=/";
}
}
您可以在Host.cshtml
和<script>
标签中添加@Flores解释的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>
如果你想避免外部脚本依赖
await jsRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{cookieValue}\"")
保留以正确转义 cookie 值。
不用脚本也可以这样使用:
首先定义这个服务:
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");
尽情享受吧。
借助 MohsenB provided. I have created a NuGet 为其打包的代码片段。
NuGet 安装:
Install-Package AltairCA.Blazor.WebAssembly.Cookie
Program.cs
builder.Services.AddAltairCACookieService(options =>
{
options.DefaultExpire = TimeSpan.FromMinutes(15);
});
使用示例
注入服务
@inject IAltairCABlazorCookieUtil _cookieUtil;
示例 1
await _cookieUtil.SetValueAsync("cookieName", "value");