我想推荐以下代码。它工作得很好(我在几个网站上使用),比@david的版本简单:
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
public class WhitespaceStrip : ActionFilterAttribute {
public override void OnActionExecuting(
ActionExecutingContext Context) {
try {
Context.HttpContext.Response.Filter = new WhitespaceFilter();
} catch (Exception) {
// Ignore
};
}
}
public class WhitespaceFilter : MemoryStream {
private HttpResponse Response = HttpContext.Current.Response;
private Stream Filter = null;
private string Source = string.Empty;
private string[] ContentTypes = new string[1] {
"text/html"
};
public WhitespaceFilter() {
this.Filter = this.Response.Filter;
}
public override void Write(
byte[] Buffer,
int Offset,
int Count) {
this.Source = Encoding.UTF8.GetString(Buffer);
if (this.ContentTypes.Contains(this.Response.ContentType)) {
this.Response.ContentEncoding = Encoding.UTF8;
this.Source = new Regex("(<pre>[^<>]*(((?<Open><)[^<>]*)+((?<Close-Open>>)[^<>]*)+)*(?(Open)(?!))</pre>)|\\s\\s+|[\\t\\n\\r]", RegexOptions.Compiled | RegexOptions.Singleline).Replace(this.Source, "$1");
this.Source = new Regex("<!--.*?-->", RegexOptions.Compiled | RegexOptions.Singleline).Replace(this.Source, string.Empty);
this.Filter.Write(Encoding.UTF8.GetBytes(this.Source), Offset, Encoding.UTF8.GetByteCount(this.Source));
} else {
this.Filter.Write(Encoding.UTF8.GetBytes(this.Source), Offset, Encoding.UTF8.GetByteCount(this.Source));
};
}
}
更新
@天哪,只是因为你说的话让我很生气
“6X”
再慢一点,我开始看你是不是对的。最后我重新编写了过滤器并清理了一点,然后运行了一些测试,在测试中我循环了一个表10000以生成一些空白空间,并查看过滤器是如何工作的。说到做到,我看不出这两个正则表达式有什么不同。
现在,如果你是在暗示表达式的工作方式不同,我的表达式会慢一些,也许这是有道理的,但是如果你看到任何不同,你必须推出超过1 MB的大小
HTML
页。。。我希望不是你在做什么。
此外,我的表达保留了
<pre>
元素。。。
所有这些都说,这是我的修订版:
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
internal class WhitespaceStripAttribute : ActionFilterAttribute {
public override void OnActionExecuted(
ActionExecutedContext ActionExecutedContext) {
ActionExecutedContext.HttpContext.Response.Filter = new WhitespaceStream(ActionExecutedContext.HttpContext);
}
}
internal class WhitespaceStream : MemoryStream {
private readonly HttpContextBase HttpContext = null;
private readonly Stream FilterStream = null;
private readonly string[] ContentTypes = new string[1] {
"text/html"
};
private static Regex WhitespaceRegex = new Regex("(<pre>[^<>]*(((?<Open><)[^<>]*)+((?<Close-Open>>)[^<>]*)+)*(?(Open)(?!))</pre>)|\\s\\s+|[\\t\\n\\r]", RegexOptions.Singleline | RegexOptions.Compiled);
private static Regex CommentsRegex = new Regex("<!--.*?-->", RegexOptions.Singleline | RegexOptions.Compiled);
public WhitespaceStream(
HttpContextBase HttpContext) {
this.HttpContext = HttpContext;
this.FilterStream = HttpContext.Response.Filter;
}
public override void Write(
byte[] Buffer,
int Offset,
int Count) {
string Source = Encoding.UTF8.GetString(Buffer);
if (this.ContentTypes.Any(
ct =>
(ct == this.HttpContext.Response.ContentType))) {
this.HttpContext.Response.ContentEncoding = Encoding.UTF8;
Source = WhitespaceRegex.Replace(Source, "$1");
Source = CommentsRegex.Replace(Source, string.Empty);
};
this.FilterStream.Write(Encoding.UTF8.GetBytes(Source), Offset, Encoding.UTF8.GetByteCount(Source));
}
}