如何在ASP.NET中设置Cookie并在Blazor WebAssembly中读取?
我需要在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**的配置:
浏览器的安全机制规定,设置了
HttpOnly属性的Cookie,禁止前端JavaScript(包括Blazor通过IJSRuntime调用的JS代码)访问,以此防范XSS攻击窃取敏感Cookie内容。这就是你用JS读取document.cookie为空的原因。若需要在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存储敏感信息(如认证令牌),不建议此操作;仅适用于非敏感数据场景。
- 修正
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
相关产品推荐
相关产品推荐

