需要压缩的页面继承BaseController,也可以参照转载原文重载RazorViewEngine的方法:
public class BaseController:Controller
{
#region 页面压缩
private HtmlTextWriter _htmlWriter;
private StringWriter _writer;
private StringBuilder _builder;
private HttpWriter _output;
private static Minifier minifier = new Minifier();
private static CodeSettings codeSettings = new CodeSettings()
{
IgnoreAllErrors = true,
MinifyCode = true,
LocalRenaming = LocalRenaming.CrunchAll
};
private static CssSettings cssSettings = new CssSettings()
{
IgnoreAllErrors = true,
OutputMode = OutputMode.SingleLine,
MinifyExpressions = true,
};
//匹配js
private static Regex regexJs = new Regex("(?<=<script(.)*?>)([\\s\\S](?!<script))*?(?=</script>)", RegexOptions.IgnoreCase);
//string regexstr=@"<script[^>]*>([\s\S](?!<script))*?</script>";
/// <summary>
/// 匹配<style>xxxxx</style>之间的内容
/// </summary>
//private static Regex regexStyle = new Regex("(?<=<style(.*?)>)(.|\n)*?(?=</style>)", RegexOptions.IgnoreCase);
private static Regex regexStyle = new Regex("(?<=<style(.)*?>)([\\s\\S](?!<script))*?(?=</style>)", RegexOptions.IgnoreCase);
private const string keyCss = "[css*.256.843.56.745.h*J.]";
private const string keyJs = "[js*.869.218.839.*W.]";
/// <summary>
///压缩html、css、js代码
/// </summary>
/// <param name="text">html代码</param>
/// <returns></returns>
private static string Compress(string html, ResultExecutedContext filterContext)
{
if (filterContext.HttpContext.Request.RequestType.ToUpper() == "GET")
{
Parallel.Invoke(() =>
{
//压缩js
var marchCollection = regexJs.Matches(html);
if (marchCollection.Count > 0)
{
foreach (Match item in marchCollection)
{
if (string.IsNullOrWhiteSpace(item.Value))
{
continue;
}
//string jsTemp = item.Value.Replace("<script>", "").Replace("</script>","").Replace("<script type=\"text/javascript\">", "");
html = html.Replace(item.Value, keyJs);
//压缩js
string minJs = minifier.MinifyJavaScript(item.Value, codeSettings);
html = html.Replace(keyJs, minJs);
}
}
}
, () =>
{
//压缩css
//是否有<style>标签
//var isHaveStyle = Regex.Match(sb.ToString(), "<style(.*)>", RegexOptions.IgnoreCase).Success;
//匹配style节点
var marchList = regexStyle.Matches(html);
if (marchList.Count > 0)
{
foreach (Match item in marchList)
{
if (string.IsNullOrWhiteSpace(item.Value))
{
continue;
}
html = html.Replace(item.Value, keyCss);
//压缩style
string minCss = minifier.MinifyStyleSheet(item.Value, cssSettings, codeSettings);
html = html.Replace(keyCss, minCss);
}
}
});
}
var reg = new Regex(@"\s*(</?[^\s/>]+[^>]*>)\s+(</?[^\s/>]+[^>]*>)\s*");
text = reg.Replace(text, m => m.Groups[1].Value + m.Groups[2].Value);
//移除html标签之间的空格
text = new Regex(@"(?<=>)[\s|\n|\t]*(?=<)").Replace(text, string.Empty);
//移除多余空格和换行符
text = new Regex(@"\n+\s+").Replace(text, string.Empty);
return html;
}
/// <summary>
/// 在执行Action的时候,就把需要的Writer存起来
/// </summary>
/// <param name="filterContext">上下文</param>
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
_builder = new StringBuilder();
_writer = new StringWriter(_builder);
_htmlWriter = new HtmlTextWriter(_writer);
_output = (HttpWriter)filterContext.RequestContext.HttpContext.Response.Output;
filterContext.RequestContext.HttpContext.Response.Output = _htmlWriter;
base.OnActionExecuting(filterContext);
}
/// <summary>
///在执行完成后,处理得到的HTML,并将他输出到前台
/// </summary>
/// <param name="filterContext"></param>
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
var response = Compress(_builder.ToString(),filterContext);
filterContext.HttpContext.Response.StatusCode = 200;
_output.Write(response);
}
#endregion
}
若压缩后的HTML有问题,可根据HTML调整正则。