架构深渊

慢慢走进程序的深渊……关注领域驱动设计、测试驱动开发、设计模式、企业应用架构模式……积累技术细节,以设计架构为宗。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

生成静态页,为什么不生成压缩静态页?

Posted on 2008-10-09 20:02  chen eric  阅读(261)  评论(0编辑  收藏  举报
iis6开启gzip后,是先将需要压缩的静态文件压缩保存在一个目录,请求来时先判断是否支持gzip,不支持直接发送静态文件,支持则再判断文件是否修改,没有就直接发送压缩的文件,有则重新生成压缩文件。

  根据我对公司的多个网站观察访问者浏览器支持gzip的高达99%以上,我就想又何必多保存一份静态文件,直接保存压缩后的文件不就ok,既节约了空间又节约了处理的过程,万一碰见那1%不到的访客,解个压给他便是。好!就这么处理,为压缩的html专门取个后缀名.ghtml。

  生成ghtml:

  首先iis注册.ghtml文件交给.net处理。

  然后将需要生成ghtml的aspx文件通过这个函数处理,也就是生成静态文件,再多一步压缩

/**///// <summary>
/// 在html目录下生成压缩html
/// </summary>
/// <param name="aspxPath">动态页面请求路径</param>
/// <param name="urlPath">静态页面请求路径</param>
public static void AspxToHtml(string aspxPath, string urlPath)
{
string filePath = HttpContext.Current.Server.MapPath(urlPath);
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath.Substring(0,filePath.LastIndexOf("")));
}
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
using (GZipStream gz = new GZipStream(fs, CompressionMode.Compress))
{
using (StreamWriter sw = new StreamWriter(gz, Encoding.UTF8))
{
HttpContext.Current.Server.Execute(aspxPath, sw,false);
sw.Flush();
}
}
}
}


  处理ghtml请求,浏览器支持gzip就直接写入文件,否则先解压内容再输出:

  自己写个HttpModule,在BeginRequest事件中处理.ghtml请求 ,静态页嘛就模拟一下html的304处理

public class FreeModule : IHttpModule
{
// Init方法仅用于给期望的事件注册方法
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}


private void SetClientCaching(HttpResponse response, DateTime lastModified)
{
response.Cache.SetETag(lastModified.Ticks.ToString());
response.Cache.SetLastModified(lastModified);
response.Cache.SetCacheability(HttpCacheability.Public);
}


// 处理BeginRequest 事件的实际代码
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
HttpRequest request=context.Request;
HttpResponse response = context.Response;





string path = context.Request.Path.ToLower();

string acceptEncoding = request.Headers["Accept-Encoding"];


bool accept = !string.IsNullOrEmpty(acceptEncoding)? acceptEncoding.ToLower().Contains("gzip") : false;






if (path.Contains(".ghtml"))
{
string filePath = request.PhysicalApplicationPath + "/html" + path;
if (!File.Exists(filePath))
{ throw new FileNotFoundException("找不到文件ghtml"); }

DateTime writeTime = File.GetLastWriteTimeUtc(filePath);
DateTime since;
if (DateTime.TryParse(request.Headers["IfModifiedSince"],out since) && writeTime == since.ToUniversalTime() )
{
response.StatusCode = 304;
response.StatusDescription = "Not Modified";
}
else

{

if (accept )
{


response.AppendHeader("Content-Encoding", "gzip");


response.TransmitFile(filePath);

}

else

{

response.Write(DezipText(filePath)); // 解压ghtml文件


}



SetClientCaching(response, writeTime);
response.End();
}
}
}
public void Dispose()
{
}
}

  解压ghtml:

  最后还有个解压ghtml函数

/**//// <summary>
/// 解压text文件后返回str
/// </summary>
/// <param name="textPath">物理路径</param>
/// <returns>文件字符串</returns>
public static string DezipText(string textPath)
{
using (FileStream fs = File.OpenRead(textPath))
{
GZipStream gz = new GZipStream(fs, CompressionMode.Decompress);
StreamReader sr = new StreamReader(gz);
return sr.ReadToEnd();
}
}