我们如何动态添加/更新元标记,以便它们被Facebook / Whatsapp共享对话框选中?
我将angular 2应用程序升级为angular 4,以便在我们从API获取组件中的数据后,使用Meta服务动态添加/更新元标记。
到目前为止,在我的组件中,我有
this.metaService.updateTag({ property: 'og:title', content: pageTitle });
this.metaService.updateTag({ property: 'og:url', 'www.domain.com/page' });
this.metaService.updateTag({ property: 'og:image', content: coverUrl, itemprop: 'image' });
this.metaService.updateTag({ property: 'og:image:url', content: coverUrl, itemprop: 'image' });
this.metaService.updateTag({ property: 'og:image:type', content: 'image/png' });
我正在使用updateTag,因为我已经添加了带有默认值的静态标记。当我检查元代码时,此代码会成功更新元标记值。
我知道Facebook / Whatsapp调试工具不执行任何javascript是有道理的,所以它不会在他们的环境中执行。
我正在使用https://developers.facebook.com/tools/debug/
,它总是选择有意义的默认标签值。
我的问题是,Facebook / Whatsapp动态获取更新的标签值的方法是什么?我正在使用Angular 4并通过API调用加载所有数据,因此在页面加载和脚本执行之前无法获取任何类型的数据。
你需要提供一个静态的html页面,其中包含og:image og:title和og:html源代码中的开放图形标签,因为facebook,twitter和co只是简单地抓取普通的HTML而不通过javascript渲染它。 Angular通过js动态更新dom,因此抓取工具只获得初始index.html。
有几种方法可以提供包含开放图形标记的html并解决您的问题:
我想你已经使用像ngx-meta这样的东西来添加og标签了吗?
我想服务器端渲染是解决问题的最合适方式。为此,您可以托管节点服务器或使用例如。 AWS Lambda。这样做的缺点是,您的应用必须主动托管,不能再以静态方式提供服务。无论如何,这似乎是最好的方式,因为它也改善了SEO。 Angular Universal是搜索的术语:
您还可以在构建过程中预呈现特定路由,并将angular作为具有多个预呈现index.html文件的静态应用程序提供。如果你只有很少的静态路由,那么这种方法非常好。考虑使用动态部件的更通用路线,这不是解决方案。去服务器端渲染。 angular universal boilerplate也包含了一个例子。见prerender.ts
如果您希望避免在构建过程中实现服务器端/预呈现(设置角度通用有时是不好的结构化应用程序的痛苦。)您可以尝试使用预呈现页面的代理服务。看看例如。 prerender.io。
将所有请求重定向到覆盖og:标记的脚本。例如。 Using PHP and .htaccess to overwrite og tags这也适用于现代环境。例如。你可以使用cloudfront / api网关和lambda函数。虽然没有见过这样的例子。
请注意,缓存可能仍然缓存了第一次爬网时打开的图形信息。确保您的源代码是最新的和所有缓存,反向代理如nginxx,cloudfront被清除。
使用Facebook Debugger调试打开的图形缓存并清除facebook打开的图形缓存
试试这个(使用fb API:v2.12):
FB.ui({
method: 'share_open_graph',
action_type: 'og.shares',
action_properties: JSON.stringify({
object : {
'og:url': 'url', // your url to share
'og:title': 'title',
'og:site_name':'site_name',
'og:description':'description',
'og:image': 'image Url',//
'og:image:width':'250',//size of image in pixel
'og:image:height':'257'
}
})
}, function(response){
console.log("response is ",response);
});
如果您正在使用Angular 4,为什么不使用Angular Universal创建页面服务器端 - 这样您就可以在浏览器加载页面之前以编程方式构建HEAD
标记
在角度6中,动态元标记不会反映在index.html中
因此,只有通过.htaccess帮助获取动态元内容的方法。
如果您想呈现所需的动态内容,请获取.htaccess的帮助。
RewriteCond%{HTTP_USER_AGENT} facebookexternalhit / 1.1 | Twitterbot | Pinterest | linkedinbot | WhatsApp | Viber | SkypeUriPreview | Google。*摘录[NC,OR]
欲了解更多信息:
https://gist.github.com/thoop/8072354
https://www.winhelp.info/create-browser-whitelist-with-htaccess.html
截至2018/19,如果您的主要目标是SEO(或者可能更多“SMO” - 社交媒体优化 - 因为Googlebot在评估JavaScript方面做得很好,但大多数社交媒体机器人都没有),您的SSR解决方案可能应该是不是Angular Universal,而是使用无头浏览器的东西。
这将属于Manuel的回答中的“代理”类别,但由于我还没有看到它们在这里发布了两个(一半)非常好的解决方案:
这个由Google Chrome团队自己维护,只是一个很好的端点,用于呈现您的应用并返回它。
就像Rendertron一样,但这个有中间件(即你在哪里以及如何决定哪些请求被渲染,哪些没有)已经内置,并且还带有一些更先进但更方便的功能,如缓存。因此它非常接近它的“零配置需要”目标,甚至比Rendertron更容易设置。
再次由谷歌Chrome团队维护(实际上由Rendertron使用)Puppeteer为无头Chrome提供基于节点的高级API。因此,如果以前的项目对你来说两个僵硬,你可能会用Puppeteer实现一个合适的解决方案,但显然它将比使用Rendertron或Rendora更多的工作。
与Angular Universal相比,这种解决方案具有巨大的优势,即您的应用程序项目可以完全与所使用的SSR工具无关(它甚至可以使用除Angular之外的任何其他技术)。这显然不仅为您自己的代码提供了更大的灵活性,也为您的包选择提供了更多的灵活性,因为您不必担心它们是否与Angular Universal兼容。它们的缺点可能是性能开销有点小,但如果你只是针对机器人这可能无关紧要。如果你使用Rendora的缓存,这可能甚至不是真的,你实际上可能会有性能提升。但是,如果这可以与Angular Universal实现的性能提升相媲美,我不知道。但请记住,当我们谈论SSR的性能提升时,我们总是只谈论第一页加载的时间。因此,通常这一点的重要性不会太高,因为您的用户在首次加载后会与您的应用进行更多互动。如果他们没有,你主要是匿名用户,只检查一个页面,然后离开你可能不会建立一个PWA,但首先是一个经典的网页...
tl; dr只需看看Rendora和Rendertron,它们可能就是你想要的东西,让你在那里非常轻松快捷。