【发布时间】:2011-12-12 13:25:07
【问题描述】:
我正在尝试将Vary: Accept-Encoding 标头添加到对我压缩的文件的响应中,as advised earlier。
但是,由于某种原因,这是不可能的 - 无论是从 Visual Studio 测试服务器还是 IIS 服务器。
我有以下代码:
if (url.Contains(".js") || url.Contains(".aspx") || url.Contains(".css"))
{
app.Response.AppendHeader("Vary", "Accept-Encoding");
app.Response.AppendHeader("Varye", "Accept-Encoding"); // for testing
app.Response.AppendHeader("Varye", "Accept-Things"); // for testing
app.Response.AppendHeader("Vary", "Accept-Stuff"); // for testing
app.Response.AppendHeader("Var", "Accept-Items"); // for testing
encodings = encodings.ToLower();
if (encodings.Contains("gzip") || encodings == "*")
{
app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "gzip");
}
}
这会产生以下响应标头:
Status=OK - 200
Server=ASP.NET Development Server/10.0.0.0
Date=Fri, 21 Oct 2011 12:24:11 GMT
X-AspNet-Version=4.0.30319
Varye=Accept-Encoding, Accept-Things
Var=Accept-Items
Content-Encoding=gzip
Cache-Control=public
Etag="1CC8F2E9D772300"
Content-Type=text/css
Content-Length=16200
Connection=Close
如您所见,Vary 标头不存在。存在具有类似语法的无意义标头,因此在发送 Vary 标头之前,一定有什么东西在某处取出。
我不知道它是否相关,但这是我在 web.config 中定义我的压缩模块的地方:
<httpModules>
<add name="CompressionModule" type="Utility.HttpCompressionModule"/>
</httpModules>
(其中 Utility.HttpCompressionModule 是我上面提供的代码摘录所属的类。)
为什么我无法添加Vary 标头?
编辑: Eric C 的解决方案给我留下了这样的代码:
if (url.Contains(".js") || url.Contains(".aspx") || url.Contains(".css"))
{
app.Response.Cache.SetVaryByCustom("Accept-Encoding");
encodings = encodings.ToLower();
if (encodings.Contains("gzip") || encodings == "*")
{
app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "gzip");
}
但是,标题看起来像这样:
Status=OK - 200
Server=ASP.NET Development Server/10.0.0.0
Date=Mon, 24 Oct 2011 09:26:37 GMT
Content-Encoding=gzip
Cache-Control=public
Etag="1CC7A09FDE77300"
Vary=*
Content-Type=application/x-javascript
Content-Length=44447
Connection=Close
(不知道为什么这是application/x-javascript,因为它在HTML中设置为text/javascript,但这无关紧要。)
如您所见,我现在有一个可变标头,但它设置为Vary=* 而不是Vary=Accept-Encoding,正如您在压缩模块中的代码中所期望的那样。
这里发生了什么?如何正确设置 Vary 标头?
第二次编辑: 我将粘贴整个班级的源代码。没有比我已经发布的更多内容了,但它可能有助于准确了解我在做什么:
public class HttpCompressionModule : IHttpModule
{
/// <summary>
/// Initializes a new instance of the <see cref="AjaxHttpCompressionModule"/> class.
/// </summary>
public HttpCompressionModule()
{
}
#region IHttpModule Members
/// <summary>
/// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
/// </summary>
void IHttpModule.Dispose()
{
}
/// <summary>
/// Initializes a module and prepares it to handle requests.
/// </summary>
/// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += (new EventHandler(this.context_BeginRequest));
}
#endregion
/// <summary>
/// Handles the BeginRequest event of the context control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
string encodings = app.Request.Headers.Get("Accept-Encoding");
Stream baseStream = app.Response.Filter;
if (string.IsNullOrEmpty(encodings))
return;
string url = app.Request.RawUrl.ToLower();
if (url.Contains(".js") || url.Contains(".css") || url.Contains("ajax.ashx"))
{
app.Response.Cache.SetVaryByCustom("Accept-Encoding");
encodings = encodings.ToLower();
if (encodings.Contains("gzip") || encodings == "*")
{
app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "gzip");
}
else if (encodings.Contains("deflate"))
{
app.Response.Filter = new DeflateStream(baseStream, CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "deflate");
}
}
}
}
此外,这是我的 web.config 文件的 System.Web 部分:
<system.web>
<!--<compilation debug="true"></compilation>-->
<trace enabled="true" traceMode="SortByTime"/>
<httpRuntime executionTimeout="180"/>
<globalization culture="en-GB" uiCulture="en-GB"/>
<!-- custom errors-->
<customErrors mode="Off">
</customErrors>
<!-- Membership -->
<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="SQLServerAuth" applicationName="mycompany" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="1024"/>
</providers>
</membership>
<!-- Roles -->
<roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="SqlProvider">
<providers>
<clear/>
<add connectionStringName="SQLServerAuth" applicationName="mycompany" name="SqlProvider" type="System.Web.Security.SqlRoleProvider"/>
</providers>
</roleManager>
<!-- Authentication -->
<anonymousIdentification enabled="false"/>
<authentication mode="Forms">
<forms name=".AUTH" protection="All" timeout="2" path="/">
</forms>
</authentication>
<httpModules>
<add name="CompressionModule" type="Utility.HttpCompressionModule"/>
</httpModules>
</system.web>
没什么好说的了。据我所知,我们在网站上没有其他非标准的东西。有什么想法吗?
【问题讨论】:
-
我通过
Response.AppendHeader和Response.AddHeader对其进行了测试,两者都可以正常工作!你能解释一下你的源代码吗? -
我再次测试它并且工作!通过
Append和Add两者!您仅将模块限制为某些扩展:if (url.Contains(".js") || url.Contains(".css") || url.Contains("ajax.ashx"))您是否使用此扩展的标头进行测试?在if中添加.aspx扩展并进行测试。代码没有任何问题,可以正常工作。 -
这对我不起作用真的很奇怪。但是,通过调试器,我已经确认
Content-Encoding逻辑正在用于我要压缩的文件,目前我的.aspx文件都设置为No-Cache或Private,我最感兴趣的是看到我的静态内容文件(相当大)是否被正确缓存。
标签: c# asp.net http-headers