什么时候发送HTTP标头?

时间:2017-06-23 17:22:53

标签: c# asp.net http http-headers httpresponse

我有这个模块:

public class SecureCookieModule : IHttpModule
{
    public void Dispose()
    {
    }

    public void Init(HttpApplication context)
    {
        context.EndRequest += OnEndRequestHandlerExecute;
    }

    private void OnEndRequestHandlerExecute(object sender, EventArgs e)
    {
        if (!AppConfig.MachineAppSettingsBool("setSecureCookiesForSecureConnections"))
        {
            return;
        }

        try
        {
            HttpApplication app = sender as HttpApplication;

            if (app.Request.IsReallySecureConnection())
            {
                foreach (string s in app.Response.Cookies.AllKeys)
                {
                    var cookie = app.Response.Cookies[s];

                    if (cookie.Secure == false)
                    {
                        cookie.Secure = true;
                        app.Response.Cookies.Add(cookie);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            LogManager.GetLogger("SecureCookieModule").Error("Exception while processing http module. Ex: {0}", ex);
        }
    }
}

根据我在某些情况下编写的内容,响应标头已经发送,因此无法修改它们并因此抛出异常。我想念的是这种情况发生的原因以及原因?为什么在某些情况下执行“OnEndRequestHandlerExecute”事件之前它们被发送,而在其他情况下它们不是?这种情况背后的规则是什么导致了这种行为?

提前致谢!

1 个答案:

答案 0 :(得分:1)

如果没有缓冲响应,并且已经发送了标头,则在结束请求事件期间无法更改它们,因为它们已经被写回到浏览器的数据流中。

要解决此问题,您可以选择:

  1. 开启response buffering。这样,您当前的代码将能够修改缓冲区中的标题(如果您提供大型文档,这可能不是一个好主意。)

    Response.BufferOutput = true;
    
  2. 而不是处理EndRequest,而是处理PreSendRequestHeaders。保证在将标头写入响应之前触发此事件。

    public void Init(HttpApplication context)
    {
        context.PreSendRequestHeaders += OnEndRequestHandlerExecute;
    }