Search Engine Optimization - Moving View State to the bottom

2016-02-19 17:15 9 1 收藏

图老师设计创意栏目是一个分享最好最实用的教程的社区,我们拥有最用心的各种教程,今天就给大家分享Search Engine Optimization - Moving View State to the bottom的教程,热爱PS的朋友们快点看过来吧!

【 tulaoshi.com - Web开发 】

  One of the greatest problems when trying to optimize an ASP.NET page to be more search engine friendly is the view state hidden field. Most search engines give more score to the content of the firsts thousands of bytes of the document so if your first 2 KB are view state junk your pages are penalized. So the goal here is to move the view state data as down as possible.

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

  I have seen some approaches to solve this problem rewriting the final HTML code of the response. While this approach works I think that it wastes some precious processor cycles that can be used to do other things. So I needed a way to do the same thing without wasting that CPU time. After some large reflector sessions I found a way to do it. My method uses the ASP.NET Control Adapter Architecture.

  A control adapter is a class that can be used to control the HTML generated by the control it adapts. Since the Page class is the responsible of rendering the view state hidden field (Page.BeginFormRender calls Page.RenderViewStateFields), an adapter for the Page is needed. However, the view state hidden field plays a key role in the ASP.NET infrastructure (for example, the Page.IsPostBack property checks if the view state hidden field has been posted) and it is difficult to modify the associated HTML.

  A PageAdapter has a method called GetStatePersister() that returns an object that inherits from PageStatePersister. The PageStatePersister is called when it is time to load and save the view state. There are 2 classes that inherit from PageStatePersister: HiddenFieldPageStatePersister and SessionPageStatePersister. The first one is the default, which stores the view state in the hidden field called __VIEWSTATE. The second one stores the view state in the session. So, we can easily create a custom PageStatePersister to control the view state load and save process. The big problem is how to create the hidden view state field before the closing form tag while being a fully transparent solution. After some tries I came up with a solution that I was happy with.

  I realized that it was impossible to completely remove the view state hidden field from the top of the page, because it plays a key role in the ASP.NET infrastructure. However, with any custom page state persister the ASP.NET infrastructure renders at least an empty view state hidden field of only 70 bytes:

  input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="" /

  My page adapter adds a hidden field to the bottom of the form called __SEOVIEWSTATE with the actual view state data, and the only limitation that it has it is that you can not use expressions directly inside the asp.net form. However, this restriction can be easily avoided putting the expression in a PlaceHolder control or inside another control. For an in-depth explanation of this limitation take a look here.

  Let’s see an example of the adapter in action. The following ASP.NET page:

%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SEOViewStateAdapterTest._Default" %!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"html xmlns="http://www.w3.org/1999/xhtml" head runat="server"    title/title/headbody    form id="form1" runat="server"    div        Enter a message: br /        asp:TextBox ID="txtMessage" runat="server"/asp:TextBoxbr /        asp:Button ID="bSaveMessage" runat="server" Text="Save Message" onclick="bSaveMessage_Click" /br /        asp:Label ID="lMessage" runat="server"/asp:Labelbr /                pPage generated at asp:PlaceHolder ID="PlaceHolder1" runat="server"%= DateTime.Now.ToString("hh:mm dd/MM/yyy") %/asp:PlaceHolder/p    /div    /form/body/html

  With the associated code:

  using System;

  using System.Collections.Generic;

  using System.Web;

  using System.Web.UI;

  using System.Web.UI.WebControls;

  namespace SEOViewStateAdapterTest

{    public partial class _Default : System.Web.UI.Page    {        protected void Page_Load(object sender, EventArgs e)        {            if (!Page.IsPostBack) {                ViewState["previousMessage"] = txtMessage.Text;            }        }        protected void bSaveMessage_Click(object sender, EventArgs e)        {            lMessage.Text = String.Format("The current message is '{0}'. The previous message was '{1}'", txtMessage.Text, (string)ViewState["previousMessage"]);            ViewState["previousMessage"] = txtMessage.Text;        }    }}

  after a couple of postbacks, without using the adapter, the HTML looks like this:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"html xmlns="http://www.w3.org/1999/xhtml" headtitle/title/headbody    form name="form1" method="post" action="Default.aspx" id="form1"divinput type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJc01l[...]VwP+cfdSWI6Q==" //divdiv    input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKb4uenCgK/1s7/DwKf8MMPfiUvZtKPSXk//XdxkLooz8QDI0Y=" //div    div        Enter a message: br /        input name="txtMessage" type="text" value="Message 2" id="txtMessage" /br /        input type="submit" name="bSaveMessage" value="Save Message" id="bSaveMessage" /br /        span id="lMessage"The current message is 'Message 2'. The previous message was 'Message 1'/spanbr /                pPage generated at 08:13 04/12/2008/p    /div    /form/body/html

  and after a couple of postbacks, using the adapter, the HTML looks like this:

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"html xmlns="http://www.w3.org/1999/xhtml" headtitle/title/headbody    form name="form1" method="post" action="Default.aspx" id="form1"divinput type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="" //divdiv    input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwL+raDpAgK/1s7/DwKf8MMPyF7nqN1AbwNwFBq8OAjEAQorsyo=" //div    div        Enter a message: br /        input name="txtMessage" type="text" value="Message 2" id="txtMessage" /br /        input type="submit" name="bSaveMessage" value="Save Message" id="bSaveMessage" /br /        span id="lMessage"The current message is 'Message 2'. The previous message was 'Message 1'/spanbr /                pPage generated at 08:11 04/12/2008/p    /div    input type="hidden" name="__SEOVIEWSTATE" id="__SEOVIEWSTATE" value="/wEPc01lc3[...]CdNY6AtgigHvU=" //form/body/html

  In order to use the adapter, you have to add a reference to the assembly and add a file called SEOViewStateAdapter.browser (the name of the file does not matter. The extension needs to be the same. Or also you could merge the contents to another file if you already have one) to the App_Browsers folder. The content of the file should be:

browsers    !-- use the adapters for all browsers --    browser refID="Default"        controlAdapters            !-- ths adapter is used to save the view and control state at the bottom of the form so the page is more friendly to search engines --            adapter controlType="System.Web.UI.Page" adapterType="Manu.Web.Adapters.SEOFriendlyViewStatePageAdapter, SEOViewStateAdapter" /        /controlAdapters    /browser/browsers

  That’s all. Enjoy!

来源:http://www.tulaoshi.com/n/20160219/1614737.html

延伸阅读
视图是一种常用的数据库对象,它将查询的结果以虚拟表的形式存储在数据中。因为视图有非常多的优点:1,可以简化操作,2,可以建立前台和后台的缓冲,3,可以合并分割数据,4,最重要的是可以提高安全性,因此在SQL中视图也占据着非常重要的地位。在这章的总结中,深刻体会到了,两种方法:1,企业管理器,2,T-SQL语句来管理视图,和四种操作...
      大多数开发人员现在还在使用if else的过程结构,曾看过jdon的banq大哥写的一篇文章,利用command,aop模式替代if else过程结构。当时还不太明白,这几天看了《重构》第一章的影片租赁案例,感慨颇深。下面我来谈一谈为什么要用state pattern替代if else,替代if else有什么好处,以及给出具体代码怎么替代if...
标签: ASP
  涉及程序: IIS    描述: 通过构造特殊的 SEARCH 请求导致 IIS 执行攻击者代码漏洞    详细: 发现 IIS 在处理 SEARCH 请求时存在漏洞,攻击者通过提交构造特殊的 IIS SEARCH 请求能重启与 IIS 相关的所有服务,而且可能远程执行任意代码。 以下代码仅仅用来测试和研究这个漏洞,如果您将其用于不正当的途径...

经验教程

744

收藏

81

精华推荐

微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部