【问题标题】:How do I create a cookie client side using blazor如何使用 blazor 创建 cookie 客户端
【发布时间】: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 中的信息。这个应用程序需要代表次要软件创建它,直到我们能够改变它。

标签: c# blazor


【解决方案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】:

    您可以在&lt;script&gt; 标签中添加@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)) 我认为
      猜你喜欢
      • 2023-03-09
      • 2021-02-04
      • 1970-01-01
      • 2020-03-28
      • 1970-01-01
      • 2019-10-29
      • 2020-09-06
      • 2017-05-29
      • 2018-01-05
      相关资源
      最近更新 更多