在开发 Web 应用时,我们经常需要处理 HTTP 请求和响应。但你是否遇到过这样的场景:尝试在返回响应数据后修改响应头,却被抛出了异常?这其实源于 HTTP 协议的一条“隐性规则”:响应头必须在响应体之前发送,响应体发送后,响应头就被锁定。今天,我们将围绕这一知识点展开,揭示这一规则的原理、ASP.NET Core 的实现,以及如何在实际开发中规避问题。
HTTP/1.1 200 OK2. 响应头 (Headers):附带的元信息,用于描述响应体的内容、缓存策略等。比如:
Content-Type: text/html Content-Length: 567
3. 响应体 (Body):实际的数据内容,比如一段 HTML、JSON,或者文件数据。通常,客户端会先接收状态行和响应头,基于这些信息决定如何解析和处理随后的响应体。
HTTP/1.1 200 OK Content-Type: text/html <html> <body>Hello World</body> </html>在这段响应中:
var app = WebApplication.Create(); app.Run(async context => { // 堆代码 duidaima.com context.Response.Headers.Append("content-type", "text/html;;charset=utf-8"); await context.Response.WriteAsync("<b>Hello world</b>"); try { context.Response.Headers.Append("X-USER", "Bill"); } catch (Exception ex) { await context.Response.WriteAsync($"<br/><br/>你不能修改Header集合,Body已经发送. Exception: {ex.Message}"); } }); app.Run();运行上面代码
var app = WebApplication.Create(); app.Run(async context => { context.Response.Headers.Append("content-type", "text/html;;charset=utf-8"); await context.Response.WriteAsync("<b>Hello world</b>"); try { if (!context.Response.HasStarted) { context.Response.Headers.Append("X-USER", "Bill"); } } catch (Exception ex) { await context.Response.WriteAsync($"<br/><br/>你不能修改Header集合,Body已经发送. Exception: {ex.Message}"); } }); app.Run();总结