Asp.net SEO优化,针对

.net 网站生成 页面后,会有 <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUIMjU3MTg5ODcPZBYCAgEPZBYeAgEPZBYCZg8QZGQWAWZkAgMPZBY">

这个是Asp.net应用ViewState技术的特征表现,专用来保存页面状态的,为了页面能在PostBack后依然能读取服务器控件原有的状态数据,Asp.net中使用了ViewState技术,而ViewState技术本质上是用一个默认名称为"__VIEWSTATE的Hidden类型表单域来保存和传递数据,然后当在大量使用viewstate时产生的value是相当夸张的(对于SEO来说)。因为我们知道很多搜索引擎的搜索结果中会看到网页大小,在内容和功能确定的前提下,网页字节数越小,打开速度越快,对搜索蜘蛛的爬行越有利。而当我们的ASP.NET页面中的<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="">value值大于200KB或更大时,对搜索是不利的。
www.ynyes.com天度网络 联系sojay.cnblogs.com
虽然我们可以通过三种级别来轻松禁用掉这些数据的往返传递:
Machine级 在machine.config中设置<pages enableViewStateMac='false' />
Application级 在Web Applicatin的web.config中设置<pages enableViewStateMac='false' />
单页面级 在该页面中设置<%@Page enableViewStateMac='false' %>或通过代码设置Page.EnableViewStateMac = false;
可是,如果我们完全能通过禁用ViewState来解决数据传输负担而且不产生副作用的话,那么可能会导致你页面上的一些功能无效。有没有什么好的办法来解决呢。
www.ynyes.com天度网络 联系sojay.cnblogs.com
在网络上找到了一些。转帖过来。

第一种,直接不再页面上输出input type=hidden name="__VIEWSTATE"。这种方法在页面没有使用viewstate的时候可以使用。


ContractedBlock.gif ExpandedBlockStart.gif Code
  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Web;
  5using System.Web.Security;
  6using System.Xml;
  7using System.Text.RegularExpressions;
  8using System.IO;
  9
 10namespace Blackant.Controls
 11ExpandedBlockStart.gifContractedBlock.gif{
 12ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 13    /// Summary description for HiddenInputFilter
 14    /// </summary>

 15    public class HiddenInputHttpModule : IHttpModule
 16ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 17ContractedSubBlock.gifExpandedSubBlockStart.gif        IHttpModule Members#region IHttpModule Members
 18
 19        public void Dispose()
 20ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 21            //throw new Exception("The method or operation is not implemented.");
 22        }

 23
 24        public void Init(HttpApplication context)
 25ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 26            //throw new Exception("The method or operation is not implemented.");
 27            context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
 28        }

 29
 30        #endregion

 31
 32ContractedSubBlock.gifExpandedSubBlockStart.gif        事件#region 事件
 33        void context_ReleaseRequestState(object sender, EventArgs e)
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 35            HttpResponse response = HttpContext.Current.Response;
 36
 37            if (response.ContentType=="text/html")
 38ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 39                HiddenInputFilter filter = new HiddenInputFilter(response.Filter);
 40                response.Filter = filter;
 41            }

 42        }

 43        #endregion

 44
 45ContractedSubBlock.gifExpandedSubBlockStart.gif        IRawPath Members#region IRawPath Members
 46        private string _rawPath = "";
 47        public string GetPath()
 48ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 49            return _rawPath;
 50        }

 51
 52        #endregion

 53    }

 54
 55    public class HiddenInputFilter : Stream
 56ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 57ContractedSubBlock.gifExpandedSubBlockStart.gif        私有成员#region 私有成员
 58     
 59        Stream responseStream;
 60        long position;
 61        StringBuilder responseHtml;
 62        #endregion

 63
 64ContractedSubBlock.gifExpandedSubBlockStart.gif        构造#region 构造
 65        public HiddenInputFilter(Stream inputStream)
 66ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 67            responseStream = inputStream;
 68            responseHtml = new StringBuilder();
 69        }

 70        #endregion

 71        
 72ContractedSubBlock.gifExpandedSubBlockStart.gif        重写的方法#region 重写的方法
 73        public override bool CanRead
 74ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 75ExpandedSubBlockStart.gifContractedSubBlock.gif            get return true; }
 76        }

 77
 78        public override bool CanSeek
 79ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 80ExpandedSubBlockStart.gifContractedSubBlock.gif            get return true; }
 81        }

 82
 83        public override bool CanWrite
 84ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 85ExpandedSubBlockStart.gifContractedSubBlock.gif            get return true; }
 86        }

 87
 88        public override void Close()
 89ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 90            responseStream.Close();
 91        }

 92
 93        public override void Flush()
 94ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 95            responseStream.Flush();
 96        }

 97
 98        public override long Length
 99ExpandedSubBlockStart.gifContractedSubBlock.gif        {
100ExpandedSubBlockStart.gifContractedSubBlock.gif            get return 0; }
101        }

102
103        public override long Position
104ExpandedSubBlockStart.gifContractedSubBlock.gif        {
105ExpandedSubBlockStart.gifContractedSubBlock.gif            get return position; }
106ExpandedSubBlockStart.gifContractedSubBlock.gif            set { position = value; }
107        }

108
109        public override long Seek(long offset, SeekOrigin origin)
110ExpandedSubBlockStart.gifContractedSubBlock.gif        {
111            return responseStream.Seek(offset, origin);
112        }

113
114        public override void SetLength(long length)
115ExpandedSubBlockStart.gifContractedSubBlock.gif        {
116            responseStream.SetLength(length);
117        }

118
119        public override int Read(byte[] buffer, int offset, int count)
120ExpandedSubBlockStart.gifContractedSubBlock.gif        {
121            return responseStream.Read(buffer, offset, count);
122        }

123
124        public override void Write(byte[] buffer, int offset, int count)
125ExpandedSubBlockStart.gifContractedSubBlock.gif        {
126            string finalHtml = System.Text.UTF8Encoding.Default.GetString(buffer, offset, count);
127            //找到<input type="hidden" name="__VIEWSTATE"
128            string pattern=@"<input type=""hidden"" name=""__VIEWSTATE""[^>]*>";
129            finalHtml=Regex.Replace(finalHtml, pattern, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
130
131            // Write the response
132            byte[] data = System.Text.UTF8Encoding.Default.GetBytes(finalHtml);
133            responseStream.Write(data, 0, data.Length);
134        }

135        #endregion

136    
137    }

138
139
140}

141

 

编译后生成的dll文件名为Blackant.Controls.dll
然后在web项目中引用这个dll
修改web.config,加入以下内容于System.Web配置节

     < httpModules >
      
< add  name ="HiddenInputFilter"  type ="Blackant.Controls.HiddenInputHttpModule,Blackant.Controls" />
    
</ httpModules >


其实核心内容很简单
HiddenInputHttpModule中如下指示使用页面过滤器
 HiddenInputFilter filter = new HiddenInputFilter(response.Filter);
response.Filter = filter;
 HiddenInputFilter 中则
string finalHtml = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
            //找到<input type="hidden" name="__VIEWSTATE"
            string pattern=@"\<input type=""hidden"" name=""__VIEWSTATE""[^\>]*\>";
            finalHtml=Regex.Replace(finalHtml, pattern, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
替换掉<input type="hidden" name="__VIEWSTATE" ..../>标签

www.ynyes.com天度网络 联系sojay.cnblogs.com

第二种:将ViewState持久化保持在服务器端,此方法不推荐使用。原文地址:
http://topic.csdn.net/u/20080530/22/ef0d36a4-6bd4-4eba-9743-b56f080b2161.html

asp.net2.0里测试的代码,放到页面中,引用using System.IO; using System.Threading;

ContractedBlock.gif ExpandedBlockStart.gif Code
 1ContractedBlock.gifExpandedBlockStart.gif解决ViewState过于庞大的问题#region 解决ViewState过于庞大的问题
 2    protected override object LoadPageStateFromPersistenceMedium()
 3ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 4        string viewStateID = (string)((Pair)base.LoadPageStateFromPersistenceMedium()).Second;
 5        string stateStr = (string)Cache[viewStateID];
 6        if (stateStr == null)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 8            string fn = Path.Combine(this.Request.PhysicalApplicationPath, @"App_Data/ViewState/" + viewStateID);
 9            stateStr = File.ReadAllText(fn);
10        }

11        return new ObjectStateFormatter().Deserialize(stateStr);
12    }

13
14    protected override void SavePageStateToPersistenceMedium(object state)
15ExpandedSubBlockStart.gifContractedSubBlock.gif    {
16        string value = new ObjectStateFormatter().Serialize(state);
17        string viewStateID = (DateTime.Now.Ticks + (long)this.GetHashCode()).ToString(); //产生离散的id号码
18        string fn = Path.Combine(this.Request.PhysicalApplicationPath, @"App_Data/ViewState/" + viewStateID);
19        //ThreadPool.QueueUserWorkItem(File.WriteAllText(fn, value));
20        File.WriteAllText(fn, value); 
21        Cache.Insert(viewStateID, value);
22        base.SavePageStateToPersistenceMedium(viewStateID);
23    }

24    #endregion

25

www.ynyes.com天度网络 联系sojay.cnblogs.com

第三种:将ViewState的位置调整到页面底部

www.ynyes.com天度网络 联系sojay.cnblogs.com

ContractedBlock.gif ExpandedBlockStart.gif Code
 1  //ViewState的Html标记的正则表达式
 2    private static readonly Regex viewStateRegex = new Regex(@"(<input type=""hidden"" name=""__VIEWSTATE"" id=""__VIEWSTATE"" value=""/w(.*)"" />)", RegexOptions.Multiline | RegexOptions.Compiled);
 3    //</form>标记的正则表达式
 4    private static readonly Regex endFormRegex = new Regex(@"</form>", RegexOptions.Multiline | RegexOptions.Compiled);
 5
 6    protected override void Render(HtmlTextWriter writer)
 7ExpandedBlockStart.gifContractedBlock.gif    {
 8        System.IO.StringWriter stringWriter = new System.IO.StringWriter();
 9        HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
10        base.Render(htmlWriter);
11
12        string html = stringWriter.ToString();
13        Match viewStateMatch = viewStateRegex.Match(html);
14        string viewStateString = viewStateMatch.Captures[0].Value;//找出ViewState的Html标记
15        html = html.Remove(viewStateMatch.Index, viewStateMatch.Length);//替换掉ViewState的html标记
16
17        Match endFormMath = endFormRegex.Match(html, viewStateMatch.Index);
18        html = html.Insert(endFormMath.Index, viewStateString);//将ViewState的Html标记插入到</form>标记之前
19        writer.Write(html);
20        
21    }

22

 

www.ynyes.com天度网络 联系sojay.cnblogs.com

不知道还有没有好的方法,解决多SEO友好的优化方式。

转载于:https://www.cnblogs.com/sojay/archive/2009/04/23/1441713.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值