假设我有一个asp.net webforms网站,我有一个分页网格视图。在gridview内部有链接到站点中的其他页面,这些链接可能是整个站点中此链接的唯一链接。目前谷歌和其他搜索引擎可能只能按照第一页上显示的链接,因为gridview寻呼机生成如下链接:
<a href="javascript:__doPostBack('GridTest','Page$2')">2</a>
因此谷歌永远无法加载其他网页来抓取链接。
我需要一种快速而肮脏的方式让谷歌索引所有隐藏在这些javascript链接中的页面。
我考虑过在css中创建一个关闭可见性的链接,该链接将加载gridview,所有记录都可见且没有分页。这是一个很好的解决方法吗?
如果我确实有这个隐藏链接,我怎么能阻止搜索引擎索引该页面(因为我不希望普通访问者访问它),但仍然关注并索引它链接到的页面。
有人有任何想法吗?谢谢你的帮助。
我喜欢科林的想法。我已经在使用自定义寻呼机控件,因此我可以控制分页链接。为了实现他的建议,我为链接按钮创建了一个控件适配器,如果你给它一个,它将允许它呈现href属性,并将回发javascript放在OnClick中(但它使得它不能使用OnClientClick与href同时的财产。
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.Adapters;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Adapters;
/// <summary>
/// This adapter allows us to specify the href attribute and have it rendered on the page.
/// When the href is specified the postback javascript will go into the onclick. The javascript will
/// cancel the href so it will post back like normal , but for people without javascript
/// the link should work, and search crawlers should be able to index the links
///
/// Styles that you can set like Font-Bold and Font-Underline are not going to work
/// you will need to use the style attribute, or set it in css
///
/// </summary>
public class LinkButtonAdapter : WebControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
LinkButton linkButton = (LinkButton)Control;
if (linkButton != null)
{
writer.WriteBeginTag("a");
writer.WriteAttribute("id", linkButton.ClientID);
if (!string.IsNullOrEmpty(linkButton.ToolTip))
{
writer.WriteAttribute("title", linkButton.ToolTip);
}
if (!string.IsNullOrEmpty(linkButton.CssClass))
{
writer.WriteAttribute("class", linkButton.CssClass);
}
if (!string.IsNullOrEmpty(linkButton.Attributes["style"]))
{
writer.WriteAttribute("style", linkButton.Attributes["style"]);
}
if (linkButton.Enabled)
{
if (!string.IsNullOrEmpty(linkButton.Attributes["href"]))
{
//if the user has set the href render it, and render the javascript in the onclick
//this will negate the client click script so be careful
writer.WriteAttribute("href", linkButton.Attributes["href"]);
string ClientScript = Page.ClientScript.GetPostBackClientHyperlink(linkButton, "");
if (!string.IsNullOrEmpty(ClientScript))
{
writer.WriteAttribute("onclick", ClientScript + ";return false;");
}
}
else
{
writer.WriteAttribute("href", Page.ClientScript.GetPostBackClientHyperlink(linkButton, ""));
if (!string.IsNullOrEmpty(linkButton.OnClientClick))
{
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, linkButton.OnClientClick);
}
}
}
else
{
writer.WriteAttribute("disabled", "disabled");
}
writer.Write(HtmlTextWriter.TagRightChar);
//apparently link buttons can contain other controls, who knew
//when they are databound, and you have the expression in between the
//tags it gets created as a LiteralControl
//the behavior for linkbuttons seems to be to overwrite whatever
//you set in the text propery with what is in between the begin and end tags
//
//Unless you have a databound control, then the text and the inner text seems
//to be concatenated together, which seems weird
//
//Also sometimes it generates literalcontrols, but removes them, and sometime it leave them
//but only if you have another non literal control inside
//
//I don't want to try to emulate this right now it is too confusing.
//Just don't use the text and the inner html at the same time, and I am leaving all controls
//that have been added
foreach (Control c in linkButton.Controls)
{
if (c is LiteralControl)
{
linkButton.Text = ((LiteralControl)c).Text;
}
else if (c is DataBoundLiteralControl)
{
linkButton.Text = ((DataBoundLiteralControl)c).Text;
}
else
{
c.RenderControl(writer);
}
}
writer.Write(linkButton.Text);
writer.WriteEndTag("a");
Page.ClientScript.RegisterForEventValidation(linkButton.UniqueID);
}
}
}
然后将其放入浏览器文件中:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.LinkButton"
adapterType="LinkButtonAdapter" />
</controlAdapters>
</browser>
</browsers>
答案 0 :(得分:2)
对GridView控件进行子类化,覆盖Render方法,然后使寻呼机的href指向您想要的页面(即Default.aspx?Page=2
),并将原始href javascript链接复制到onclick事件。
所以您的链接将成为
<a href="Page2.aspx" onclick="javascript:__doPostBack('GridTest','Page$2')">Page 2</a>
现在重要的是,将return false;
附加到onclick事件,这样就会成为
<a href="Page2.aspx" onclick="javascript:__doPostBack('GridTest','Page$2');return false;">Page 2</a>
因为首先调用onclick方法ALWAYS,它将触发回发,但return false
将结束href
属性的处理。这样,ASP.NET得到了它的回发,谷歌得到了它的href。
现在,对于大多数重要的事情:你需要确保GridView也响应Request.QueryString["Page"]
值,否则就没有必要进行整个练习,谷歌不会看到内容的第二页?
答案 1 :(得分:0)
ASP.NET真的无法生成可以遵循的链接吗?除此之外,禁用JavaScript的用户也无法使用该网站。
自从我使用ASP.NET以来已经有一段时间了(我编写了所有自己的控件,因为当时微软的控件非常令人震惊),但你可以通过子类化控件来创建可行的链接并重写其Render方法。实际上没有理由通过脚本使用HTTP POST提交表单来模拟导致HTTP GET的简单链接。
答案 2 :(得分:0)
您可以在&lt; noscript&gt;内转出非javascript版本的页面。标签。这样,链接对于任何浏览器或机器人都是可见的。作为一项特殊的额外奖励,您甚至可以让无法使用javascript的人访问它。例如,盲人使用文本来表达观众。