我正在使用长期异步 HTTP 连接通过 AJAX 向客户端发送进度更新。启用压缩后,不会以离散 block 的形式接收更新(原因很明显)。禁用压缩(通过将 <urlCompression>
元素添加到 <system.webServier>
)确实解决了问题:
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
但是,这会在站点范围内禁用压缩。我想为除此之外的所有其他 Controller 和/或操作保留压缩。这可能吗?或者我是否必须使用自己的 web.config 创建一个新站点/区域?欢迎提出任何建议。
附言写入 HTTP 响应的代码是:
var response = HttpContext.Response;
response.Write(s);
response.Flush();
最佳答案
@Aristos 的回答适用于 WebForms,但在他的帮助下,我采用了更符合 ASP.NET/MVC 方法的解决方案。
创建一个新过滤器以提供 gzip 压缩功能:
public class GzipFilter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var context = filterContext.HttpContext;
if (filterContext.Exception == null &&
context.Response.Filter != null &&
!filterContext.ActionDescriptor.IsDefined(typeof(NoGzipAttribute), true))
{
string acceptEncoding = context.Request.Headers["Accept-Encoding"].ToLower();;
if (acceptEncoding.Contains("gzip"))
{
context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
context.Response.AppendHeader("Content-Encoding", "gzip");
}
else if (acceptEncoding.Contains("deflate"))
{
context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
context.Response.AppendHeader("Content-Encoding", "deflate");
}
}
}
}
创建 NoGzip
属性:
public class NoGzipAttribute : Attribute {
}
使用 web.config 阻止 IIS7 压缩:
<system.webServer>
...
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
</system.webServer>
在 Global.asax.cs 中注册您的全局过滤器:
protected void Application_Start()
{
...
GlobalFilters.Filters.Add(new GzipFilter());
}
最后,使用NoGzip
属性:
public class MyController : AsyncController
{
[NoGzip]
[NoAsyncTimeout]
public void GetProgress(int id)
{
AsyncManager.OutstandingOperations.Increment();
...
}
public ActionResult GetProgressCompleted()
{
...
}
}
附言再次非常感谢@Aristos,感谢他提供的有益想法和解决方案。
关于c# - 可以在 ASP.NET/IIS 7 中有选择地禁用 gzip 压缩吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5656332/