虽然它提供了一种生成规范网址的好方法,但已被接受。
这是自取其辱的捷径!!
完全破坏了使用canonical标签的意义!
为什么存在规范标签?
当 google 抓取您的网站并发现重复的内容时,您会受到惩罚。
可以通过各种路径访问您网站中的同一页面。
http://yourdomain.com/en
https://yourClientIdAt.YourHostingPacket.com/
http://195.287.xxx.xxx //Your server Ip
https://yourdomain.com/index
http://www.yourdomain.com/
http://www.yourdomain.com/index .....etc... etc..
Google 会在各种路径中找到相同的内容,从而重复内容,从而受到惩罚。
虽然最好的做法是使用 301 重定向并且只有 1 个链接指向同一个网页,这很痛苦......
这就是创建 rel="canonical" 的原因。它是一种告诉爬虫的方法
“嘿,这不是一个不同的页面,这是 www.mydomain.index 页面
您之前搜索过....规范标签中的链接是正确的!”
这样同一个网页就不会被多次抓取为不同的网页。
通过从你刚才说的 url 动态生成规范链接....
<link href="http://yourdomain.com" rel="canonical">
是的....这是一个不同的页面抓取这个也是....
<link href="http://www.yourdomain.com/index" rel="canonical">这是一个不同的......而这个......
因此,为了获得有效的规范标签,您必须为每个具有不同内容的页面生成完全相同的链接。确定您的主要域(www.etc.com)、协议 (Https/Http) 和Letter Casing(/Index,/index) 并生成与唯一符合以下条件的内容的链接标识单个页面。
这是您的Controller/Action(也许还有language)组合。
因此,您可以从您的路线数据中提取这些值。
public static TagBuilder GetCanonicalUrl(RouteData route,String host,string protocol)
{
//These rely on the convention that all your links will be lowercase!
string actionName = route.Values["action"].ToString().ToLower();
string controllerName = route.Values["controller"].ToString().ToLower();
//If your app is multilanguage and your route contains a language parameter then lowercase it also to prevent EN/en/ etc....
//string language = route.Values["language"].ToString().ToLower();
string finalUrl = String.Format("{0}://{1}/{2}/{3}/{4}", protocol, host, language, controllerName, actionName);
var canonical = new TagBuilder("link");
canonical.MergeAttribute("href", finalUrl);
canonical.MergeAttribute("rel", "canonical");
return canonical;
}
为了让您的 HtmlHelper 生成与您的约定一致的链接,@Muhammad Rehan Saeed 回答了这个问题。
然后,为了为所有页面生成规范标签,您必须制作 HtmlHelper 扩展
public static MvcHtmlString CanonicalUrl(this HtmlHelper html,string host,string protocol)
{
var canonical = GetCanonicalUrl(HttpContext.Current.Request.RequestContext.RouteData,host,protocol);
return new MvcHtmlString(canonical.ToString(TagRenderMode.SelfClosing));
}
@Html.CanonicalUrl("www.mydomain.com", "https");
或者为你的控制器实现一个动作过滤器属性。 (我使用这种方法是为了在同一个应用程序上处理具有多个域的更复杂的场景等......)
public class CanonicalUrl : ActionFilterAttribute
{
private string _protocol;
private string _host;
public CanonicalUrl(string host, string protocol)
{
this._host = host;
this._protocol = protocol;
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var canonical = GetCanonicalUrl(filterContext.RouteData,_host,_protocol);
filterContext.Controller.ViewBag.CanonicalUrl = canonical.ToString();
}
}
}
在控制器中使用
[CanonicalUrl("www.yourdomain.com","https")]
public class MyController : Controller
然后我在我的 _Layout.chtml 上使用它并完成了!
@Html.Raw(ViewBag.CanonicalUrl)