我正在尝试添加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核心模板是否设置不正确?
答案 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();
}
});
您的每个服务都必须使用正确的元数据重写索引。让我们以 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;
}
}