Cloudfront和Lambda @ Edge - 根据用户代理从自定义源获取

时间:2017-11-27 18:59:10

标签: amazon-s3 aws-lambda amazon-cloudfront

我正在通过将其上传到S3(默认根对象index.html with Cache-Control:max-age = 0,no-cache,指向指纹js / css资产)并配置我的JavaScript应用程序(SPA)来提供服务它是CloudFront发行版的起源。我的域名,假设 SomeMusicPlatform.com 在Route53中有一个包含分发网址的CNAME条目。这很好用,所有都很好缓存。

现在我想为机器人和社交网络抓取工具提供预呈现的HTML版本。我已经设置了一个服务器,该服务器在 prerendered.SomeMusicPlatform.com 域中使用预呈现版本的JavaScript应用程序(SPA)进行响应。

我在lambda函数中尝试做的是检测用户代理,识别机器人并从我的自定义服务器为它们提供预渲染版本(而不是像我通常用于普通浏览器的S3中的JavaScript内容)

我认为我可以通过使用Lambda@Edge: Using an Origin-Request Trigger to Change From an Amazon S3 Origin to a Custom Origin函数来实现此目的,该函数将原点切换到我的自定义预渲染服务器,以防它在响应头中标识爬虫机器人(或者,在测试阶段,使用{{1查询参数)。

问题在于,Lambda @ Edge函数的Origin-Request触发器未触发,因为CloudFront仍然具有缓存的默认根对象prerendered=true,并且倾向于从缓存的边缘返回内容。我使用index.htmlX-Cache:RefreshHit from cloudfront得到SomeMusicPlatform.com/?prerendered=true,即使默认根对象上有SomeMusicPlatform.com - index.html。

如何通过CloudFront保持我的JavaScript SPA的缓存服务和低延迟,并为我的自定义预呈现服务器添加服务内容,仅供爬虫机器人使用?

1 个答案:

答案 0 :(得分:1)

缓存问题(在使用mywebsite.com/?prerendered=truemywebsite.com时获得相同的匹配)通过将prerendered添加到cloudfront分发中的查询白名单来解决。这意味着CloudFront现在可以正确维护网站内容的正常版本和预渲染版本,具体取决于参数的存在(不提供来自S3源的参数缓存内容,以及使用lambda函数中指定的自定义源的参数缓存内容)送达)。

这对于测试阶段来说足够了 - 以确保机制正常运行。然后我按照迈克尔的建议,在查看器请求触发器中添加了另一个lambda函数,如果在Is-Bot中检测到机器人,则会添加自定义标头User-Agent。同样,需要白名单,这次是自定义标头(根据自定义标头维护两个源的缓存)。然后,Origin Request触发器中的另一个lambda函数决定使用哪个源,具体取决于Is-Bot标头。