使用.net核心中的angular更新og / meta标记

时间:2018-03-28 20:58:01

标签: angular asp.net-core-2.0

我正在尝试添加facebook将拾取的og标签,并且从我在网上找到的内容,它听起来像角度通用现在合并为角度,应该能够通过使用平台浏览器库来做到这一点。

我开始了一个全新的.net核心项目,带有角度支持。它创建了3个角度组件,我希望我可以测试以尝试设置og标签 - counter.component.ts,fetchdata.component.ts和home.component.ts。下面是我在counter.component.ts构造函数中的示例。

constructor(private meta: Meta) {
    this.meta.addTags([
        { property: 'og:url', content: 'https://www.oursite.com/counter' },
        { property: 'og:title', content: 'Counter Page' },
        { property: 'og:description', content: 'Counter page description' },
        { property: 'og:image', content: 'https://www.oursite.com/images/angular/counter-page.png' }
    ], false);
}

当我运行它并查看源代码时,它实际上会添加og标记,但它们会在app标记内部自己的html结构中呈现。

<html>
  <body>
    <app>
      <html>
        <head>
          <meta property="og:title" content="Counter Page">

我找到了一些boot.server.ts文件的代码,它删除了只留下元数据的额外标签,但由于它们不在实际的头标签中,因此facebook的调试器仍然没有接他们。

resolve({
   html: state.renderToString()
       .replace('<html><head>', '')
       .replace('</head><body>', '')
       .replace(/<\s*app.*?>/, '')
       .replace('</app></body></html>', '')
});

我所阅读的所有内容都让人觉得这就是它应该如何工作以及它的SEO /社交媒体友好。但显然不是。我不确定这是否打算如何运作,或者.net核心模板是否设置不正确?

2 个答案:

答案 0 :(得分:0)

我不认为这是准确的:“听起来像角度通用现在合并为角度,应该能够通过使用平台浏览器库来做到这一点。”他们在Angular 4中添加了MetaService,但这与将Angular Universal的服务器端渲染功能添加到Angular不同。

Facebook和Twitter抓取工具(与Google不同)不执行任何JavaScript,因此您必须通过服务器端渲染来执行此操作。我是通过切换到Angular Universal然后使用MetaService来完成的。

请注意,移植到Angular Universal可能是一个重大变化,因此在决定是否要实现跨越之前,请先进行研究。

答案 1 :(得分:0)

我尝试了一种在我的网站中使用的解决方法。不幸的是,facebook 还不能很好地识别它,但我会尽快弄明白它的更新。 使用 NET.5 workarround 的 Angular 11 Meta 标签 21/1/2021 12:2:47 使用 NET 5 workarround 的 Angular 11 Meta 标签 https://softease.ro/news/angular-11-meta-tags-using-net-5-workarround

如何使用特定页面的正确元标记从 .NET 5 提供 Angular SPA。

1.在你的启动中声明这个中间件。这将做的是,当路径是我们知道它必须具有不同元的路径时,用正确的元重写索引。

  app.Use(async (context, next) =>
           {
               await next();
               if (context.Response.StatusCode == 404 &&
                  !Path.HasExtension(context.Request.Path.Value) &&
                  !context.Request.Path.Value.StartsWith("/api/"))
               {
                   var path = context.Request.Path;
                   if (path.Value.Contains("/view-product/"))
                   {
                       try
                       {
                           var idxPath = Path.Combine(env.ContentRootPath, "wwwroot", "index.html");
                           var index = File.ReadAllText(idxPath);
                           index = ViewProductService.GetMeta(index, path.Value);
                           context.Response.StatusCode = 200;
                           await context.Response.WriteAsync(index);
                           return;
                       }
                       catch
                       {
                       }
                   }
                   else if (path.Value.Contains("/news/"))
                   {
                       try
                       {
                    

   var idxPath = Path.Combine(env.ContentRootPath, "wwwroot", "index.html");
                       var index = File.ReadAllText(idxPath);
                       index = NewsService.GetMeta(index, path.Value);
                       context.Response.StatusCode = 200;
                       await context.Response.WriteAsync(index);
                       return;
                   }
                   catch
                   {
                   }
               }
               context.Request.Path = "/index.html";
               await next();
           }
       });
  1. 您的每个服务都必须使用正确的元数据重写索引。让我们以 NewsService GetMeta 为例:

        var res = (from x in UOW.DbContext.News
                       where (x.Id_News.ToString() == newsId || x.PermaLink == newsId)
                       select new IndexMetaModel()
                       {
                           OgTitle = settings.DisplayName + " " + x.Subject,
                           OgDescription = x.ShortDescription,
                           OgUrl = Globals.AppUrl + "/news/" + x.PermaLink + "/"
                       }).FirstOrDefault();
    

从数据库中读取并转换为我们的元模型。在 IndexMetaUtil.ReplaceTags 中运行模型。

var resIdx = IndexMetaUtil.ReplaceTags(res, index);

return resIdx;

奖励:

对请求使用缓存:

  if (NewsDomainService.MetaIndex.ContainsKey(path))
       {`enter code here`
           return NewsDomainService.MetaIndex[path];
       }`enter code here`

IdexMetaUtil:

   public static class IndexMetaUtil
   {
       public static string ReplaceTags(IndexMetaModel meta, string index)
       {
           HtmlDocument doc = new HtmlDocument();
           doc.LoadHtml(index);
           var list = doc.DocumentNode.SelectNodes("//meta");
           bool vidFound = false;
           foreach (var node in list)
           {
               string property = node.GetAttributeValue("property", "");
               string value = "";
               switch (property)
               {
                   case "og:title":
                       value = meta.OgTitle;
                       node.SetAttributeValue("content", value);
                       break;
                   case "description":
                   case "og:description":
                       var hd = new HtmlDocument();
                       hd.LoadHtml(meta.OgDescription);
                       value = hd.DocumentNode.InnerText;
                       node.SetAttributeValue("content", value);
                       break;
                   case "og:image":
                       if (!vidFound)
                           value = meta.OgImage;
                       node.SetAttributeValue("content", value);
                       break;
                   case "og:url":
                       value = meta.OgUrl;
                       node.SetAttributeValue("content", value);
                       break;
               }
           }
           return doc.DocumentNode.OuterHtml;
       }
   }