You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET中设置Cookie并在Blazor WebAssembly中读取?

问题:Blazor WebAssembly无法读取API设置的Cookie

我需要在API中创建一个Cookie,以便在Blazor WebAssembly页面中读取。服务器端已成功创建Cookie(通过浏览器F12的Application面板可验证),但无法在Blazor页面中读取它。

服务器端代码

namespace BlazorCookie.Server.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class GetCookieController : ControllerBase
    {
        public string Get()
        {
            CookieOptions cookieOptions = new CookieOptions
            {
                Secure = true,
                Expires = DateTimeOffset.UtcNow.AddDays(1),
                HttpOnly = true,
                IsEssential = true,
                Path = "/",
                SameSite = SameSiteMode.Lax,
            };

            HttpContext.Response.Cookies.Append("MyCookie", "ASDFJKL12345", cookieOptions);

            return "This is a fine kettle of fish with a cookie.";
        }
    }
}

Blazor页面代码

@page "/getcookie"
<h3>GetCookie</h3>
<button class="btn btn-primary" @onclick="CallAPI">Get The Cookie</button>
<p>@someText</p>
@code {
    [Inject] HttpClient _http { get; set; }
    [Inject] IJSRuntime _jsRuntime { get; set; }

    string? someText { get; set; }
    private async Task CallAPI()
    {
        try
        {     
            // 调用返回名为'MyCookie'响应Cookie的API
            // 通过浏览器开发者工具已验证Cookie确实返回
            HttpResponseMessage response = await _http.GetAsync("api/getcookie");
            response.EnsureSuccessStatusCode();
            someText = await response.Content.ReadAsStringAsync();
            // 尝试调用JS函数获取"MyCookie" - 返回空值
            Lazy<Task<IJSObjectReference>> moduleTask = new(() => _jsRuntime.InvokeAsync<IJSObjectReference>("import", "/cookieUtil.js").AsTask());
            var module = await moduleTask.Value;
            var theValue = await module.InvokeAsync<string>("theCookieGetter", "MyCookie");            
            // JS方法无效,查看响应头是否包含Cookie
            foreach(var header in response.Headers)
            {
                foreach (var value in header.Value)
                {
                    Console.WriteLine($"responseHeader: {header.Key}: {value}");
                }
            }
            // 没有结果,再查看请求消息头
            foreach (var header in response.RequestMessage.Headers)
            {
                foreach (var value in header.Value)
                {
                    Console.WriteLine($"requestHeader: {header.Key}: {value}");
                }
            }
            // 仍然为空
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);    
        }
    }
}

读取Cookie的JS代码

export async function theCookieGetter(cname) {
        let name = cname + "=";
        let decodedCookie = decodeURIComponent(document.cookie);
        let ca = decodedCookie.split(';');
        for (let i = 0; i < ca.length; i++) {
            let c = ca[i];
            while (c.charAt(0) == ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                return c.substring(name.length, c.length);
            }
        }
        return "";
    }

更新说明

我已验证API响应中包含Set-Cookie头,且Blazor WebAssembly页面已成功设置Cookie(后续请求API时,请求中包含MyCookie)。但问题在于无法在Blazor客户端读取该Cookie内容,已添加credentials:include请求头,但仍无法读取。这是Blazor WebAssembly项目,而非Blazor Server。

添加的代码如下:

if (!_http.DefaultRequestHeaders.Contains("credentials"))
{
    _http.DefaultRequestHeaders.Add("credentials", "include");
}

解决方案

问题核心在于**HttpOnly = true**的配置:

  1. 浏览器的安全机制规定,设置了HttpOnly属性的Cookie,禁止前端JavaScript(包括Blazor通过IJSRuntime调用的JS代码)访问,以此防范XSS攻击窃取敏感Cookie内容。这就是你用JS读取document.cookie为空的原因。

  2. 若需要在Blazor客户端读取Cookie内容,需修改服务器端的Cookie配置,将HttpOnly设为false:

CookieOptions cookieOptions = new CookieOptions
{
    Secure = true,
    Expires = DateTimeOffset.UtcNow.AddDays(1),
    HttpOnly = false, // 修改此处
    IsEssential = true,
    Path = "/",
    SameSite = SameSiteMode.Lax,
};

注意:关闭HttpOnly会降低安全性,若该Cookie存储敏感信息(如认证令牌),不建议此操作;仅适用于非敏感数据场景。

  1. 修正credentials的配置方式:Blazor WebAssembly中,HttpClient的凭证配置不应通过请求头添加,而应使用BrowserRequestCredentials:
    • 单个请求配置:
      var request = new HttpRequestMessage(HttpMethod.Get, "api/getcookie");
      request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
      var response = await _http.SendAsync(request);
      
    • 全局配置(在Program.cs中):
      builder.Services.AddScoped(sp => new HttpClient { 
          BaseAddress = new Uri(builder.HostEnvironment.BaseAddress),
          DefaultRequestVersion = HttpVersion.Version20
      }.SetBrowserRequestCredentials(BrowserRequestCredentials.Include));
      

完成以上修改后,前端JS就能正常读取到Cookie内容,Blazor也可通过IJSRuntime获取对应值。

内容的提问来源于stack exchange,提问作者twreynol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:43:27