Aspx页面转静态页面
為客戶在SharePoint的基礎上搭建了一個門戶,但是客戶又反映說首頁打開太慢,通過Fillder工具查看,頁面打開速度大概在5秒左右。
?? 其實對于一個SharePoint站點來講,打開速度在3-4秒還是一個可以接受的范圍,但是我們的首頁放了太多的內容,包括圖片、Flash、還有N多個WebPart,以至于要不斷的從數據庫交互。
?? 首先想到的解決方案是在頁面上加Cache,從Web層到數據層都可以考慮加Cache,但是這個方法很快就被否決了。因為SharePoint2007還不支持對自定義的頁面加載Cache。
?? 第二個解決方案,生成靜態頁面,當用戶訪問時,讓其訪問靜態頁面。
?? 關于生成靜態頁面,方法還是很多的,簡單列舉下:
?? 1、ASP.NET下Page的RenderControl方法本身就是返回生成的HTML代碼,該方法在前面的隨筆中有提到;
?? 2、Page.Server.Execute(url,stringwriter)方法,只對該方法做了測試,有時間再深刻鉆研;
?? 簡單代碼:
??public bool ExecAspxToHtml()
?? {
?? StringWriter strWriterHTML = new StringWriter();
?? System.Web.UI.Page aspxPage = new System.Web.UI.Page();
?? aspxPage.Server.Execute(strAspxUrl, strWriterHTML);//將aspx頁執行產生的html輸出到StringWriter中
?? StreamWriter streamWriter = new StreamWriter(strHtmlFile, true, System.Text.Encoding.GetEncoding("GB2312"));
?? streamWriter.Write(strWriterHTML.ToString());
?? strWriterHTML.Close();
?? streamWriter.Close();
?? return true;
?? }
?? 3、模擬HttpWebRequest,獲取HttpWebResponse,采用這種方式來生成。
?? 簡單說頁面運行的機制:當我們在地址欄里輸入網址后,第一次向服務器拋Request,客戶端獲取到該Request產生的Response后,對其內部的Html代碼分析,對src,href等鏈接的文件則繼續拋Request,獲取Response,知道頁面中需要的文件都下載到客戶端,頁面才能完全打開。
?? 決定了用第三種方案,對頁面生成的HTMl代碼,需要將其生成如 src 引用的鏈接文件同時下載到本地,對href引用的鏈接需要將其更改為絕對路徑。需要考慮的問題:
?? 1、對頁面內src 的Url進行分析,繼續繼續拋HttpWebRequest獲取該文件,保存到本地,同事更改其src屬性為本地相對路徑。
?? 2、對頁面的href 的url進行分析,在其url前加上網站的服務器名,成為絕對路徑。
?? 最主要的是這兩個問題,當然還有像Background中鏈接的圖片。對于這些url,我都采用了 Regex的匹配以及替換的方法。感覺正則表達式還是很強大的。
?? 代碼:
?? //URL,用戶名都是寫在配置文件中的
?? public void ExecuteAspxToHtml()
?? {
?? DistributeRequest(CreateWebRequest(strAspxUrl));
?? }
?? private HttpWebRequest CreateWebRequest(string url)
?? {
?? HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
?? request.ContentType = "application/x-www-form-urlencoded";
?? request.Method = "GET";
?? request.Credentials = CreateCredential();
?? return request;
?? }
?? private ICredentials CreateCredential()
?? {
?? ICredentials credential;
?? //獲取配置文件中的值
?? if (!string.IsNullOrEmpty(GetAppValue("Domain")))
?? {
?? credential = new NetworkCredential(GetAppValue("UserName"), GetAppValue("Password"), GetAppValue("Domain"));
?? }
?? else
?? {
?? credential = new NetworkCredential(GetAppValue("UserName"), GetAppValue("Password"));
?? }
?? return credential;
?? }
?? private void DistributeRequest(HttpWebRequest request)
?? {
?? HttpWebResponse response = (HttpWebResponse)request.GetResponse();
?? if (response.StatusCode == HttpStatusCode.OK)
?? {
?? if (Directory.Exists(strHtmlPath))
?? {
?? Directory.CreateDirectory(strHtmlPath);
?? }
?? BinaryReader rsReader = new BinaryReader(response.GetResponseStream());
?? byte[] buffer = rsReader.ReadBytes((int)response.ContentLength);
?? //對其內部URl進行分析,獲取文件
?? GetContainUrl(response.ContentType, ref buffer);
?? if (!CompareFile(buffer))
?? {
?? FileStream fStream = new FileStream(strHtmlPath + strHtmlFile, FileMode.Create, FileAccess.Write);
?? fStream.Write(buffer, 0, buffer.Length);
?? fStream.Close();
?? response.Close();
?? }
?? }
?? }
?? private void DistributeRequest(HttpWebRequest request, string filePath, string fileName)
?? {
?? try
?? {
?? HttpWebResponse response = (HttpWebResponse)request.GetResponse();
?? if (response.StatusCode == HttpStatusCode.OK)
?? {
?? if (Directory.Exists(filePath))
?? {
?? BinaryReader rsReader = new BinaryReader(response.GetResponseStream());
?? byte[] buffer = rsReader.ReadBytes((int)response.ContentLength);
?? FileStream fStream = new FileStream(filePath + fileName, FileMode.Create, FileAccess.Write);
?? fStream.Write(buffer, 0, buffer.Length);
?? fStream.Close();
?? response.Close();
?? }
?? }
?? }
?? catch(Exception ex)
?? {
?? Console.WriteLine(ex.Message);
?? Console.WriteLine(request.RequestUri.ToString());
?? Console.WriteLine("URI錯誤");
?? }
?? }
?? private void GetContainUrl(string ContentType, ref byte[] buffer)
?? {
?? Encoding encode = System.Text.Encoding.GetEncoding("UTF-8");
?? string strbuffer = encode.GetString(buffer);
?? strbuffer = HandleSrc(strbuffer);
?? strbuffer = HandleHref(strbuffer);
?? buffer = encode.GetBytes(strbuffer);
?? }
?? /// <summary>
?? /// 對以src=""形式的鏈接,獲取其文件保存到本地
?? /// </summary>
?? /// <param name="strBuffer"></param>
?? /// <returns></returns>
?? private string HandleSrc(string strBuffer)
?? {
?? Console.WriteLine("Handle the src property to get file");
?? Console.WriteLine("*************************************");
?? Regex regex = new Regex(srcRegex, RegexOptions.IgnoreCase);
?? MatchCollection matchs = regex.Matches(strBuffer);
?? foreach (Match item in matchs)
?? {
?? if (item.Success)
?? {
?? string matchContent = item.Value;
?? string filePathName = GetFilePathName(matchContent);
?? string fileUrl = GetFileUrl(matchContent);
?? string filePath = filePathName.Substring(0,filePathName.LastIndexOf('\\'));
?? if (!Directory.Exists(strHtmlPath + filePath))
?? {
?? Directory.CreateDirectory(strHtmlPath + filePath);
?? }
?? //if (!IsUrlFileExist(strHtmlPath, filePathName))
?? //{
?? DistributeRequest(CreateWebRequest(fileUrl), strHtmlPath, filePathName);
?? //}
?? }
?? }
?? Console.WriteLine("*************************************************");
?? Console.WriteLine("Handle the src property and get file completed");
?? Console.WriteLine();
?? //上邊的循環可以放在處理中再拋Request,這里還沒有改回來
?? return regex.Replace(strBuffer, new MatchEvaluator(SrcMatchHandle));
?? }
?? private string HandleHref(string strBuffer)
?? {
?? Console.WriteLine("Handle the href property to change the relative link to absolute link");
?? Console.WriteLine("************************************************************************");
?? Regex regex = new Regex(hrefRegex, RegexOptions.IgnoreCase);
?? //MatchCollection matchs = regex.Matches(strBuffer);
?? return regex.Replace(strBuffer, new MatchEvaluator(HrefMatchHandle));
?? }
?? //返回要替換的字符串,即本地的相對路徑
?? //該方法在替換時也是遍歷執行的,因此可以在該方法里獲取文件
?? private string SrcMatchHandle(Match match)
?? {
?? if (match.Success)
?? {
?? return GetFileRelatvePath(match.Value);
?? }
?? return match.Value;
?? }
?? private string HrefMatchHandle(Match match)
?? {
?? if (match.Success)
?? {
?? return match.Value.Insert(match.Value.IndexOf('/'), strAspxPath);
?? }
?? return match.Value;
?? }
?? 其實還是投機了,因為客戶看中的只是首頁,如果要讓我去做所有頁面的靜態化,那可真是頭疼,涉及到的各種各樣的鏈接都需要考慮。
?? 現在開發工作已經完成,打算做成一個Windos服務部署到服務器,定時更新頁面。還是第一次,正在研究,有經驗的朋友可以探討下。
?? 目標是為了解決SharePoint首頁反應慢的,不過技術全是.Net的技術。??
總結
以上是生活随笔為你收集整理的Aspx页面转静态页面的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 京东e卡必须一次用完吗
- 下一篇: 通用权限实现的核心设计思想