问题 单页应用+ Amazon S3 + Amazon CloudFront + Prerender.io - 如何设置?


  1. 我有使用Backbone.js构建的单页面应用程序。
  2. 我在Amazon S3上托管应用程序(应用程序仅包含静态文件)。
  3. 我使用CloudFront作为Bucket CDN。
  4. 应用程序访问 https://myapp.com -> https://abcdefgh34545.cloudfront.com -> https://myBucket.s3-eu-west-1.amazonaws.com/index.html

我怎么用 Prerender.io 用这个堆栈服务?我必须以某种方式检测WebSpider / WebRobot正在访问该页面并将其重定向到prerender.io ...


5429
2018-03-13 15:23


起源

您无法配置cloudfront以按请求的标头值缓存html。基本上,如果请求来自机器人并且缓存该请求的预渲染版本和浏览器请求的非预渲染版本,则您将确定通过标头。 - drogon
这是一个只有一个grunt命令的完整答案: stackoverflow.com/questions/23043336/... - Robycool


答案:


Prerender.io很难与静态Amazon S3站点一起使用。

你可以在s3前站起来一个nginx / apache服务器: https://myapp.com  - > https://mynginx-server.com  - > https://myBucket.s3-eu-west-1.amazonaws.com/index.html

此解决方案不太理想,因为您失去了云端的最近位置优势。

这是一篇关于自定义解决方案的好文章: http://www.dave.cx/post/23/prerendering-angular-s3/

David能够生成静态HTML并将其保存在S3中,然后使用CloudFlare检测URL中的_escaped_fragment_并将其重定向到S3上的静态HTML。


4
2018-03-22 22:57



S3支持数据的反向代理设置不是理想的解决方案,但它仅提供对具有缓存功能和传送优化(如SPDY)的S3文件的完全受控访问。 CloudFront仅优化文件地理位置,但不优化传递速度(TCP拥塞窗口和内核设置)。 - Anatoly
我同意。它并不理想,但它是完全S3托管网站的唯一解决方案之一。 - Prerender.io
存档的博客文章可以在 web.archive.org/web/20140405234445/http://www.dave.cx/post/23/... - user1429980


我设法通过不使用Prerender但创建AWS Lambda函数来实现这一点:

  • 从CloudFront请求原始页面(它实际上始终是相同的index.html)
  • 通过API Gateway catch-all代理映射lambda函数
  • 研究路径并弄清楚应该是什么资源页面(在我的例子中它只是/ user / {name},所以我只需要做一个用例
  • 发出REST API请求以获取用户的动态数据
  • 正则表达式用动态元字段替换现有的元字段
  • 使用新的metas返回新的索引文件

配置新原点(新lambda函数)和行为(map / user / *请求到这个新原点)。请确保对源使用“仅HTTPS”原始协议策略,因为API网关仅为HTTPS,此处重定向将导致主机名更改。

(如果您偶然使用了重定向,那么您将需要Invalidate“/ *”,因为一些CloudFront错误,配置更改将无济于事;我花了几个小时调试这个昨晚)


5
2017-10-18 21:58



这是一个很好的解决方案!看起来这只是可能的 2016年9月。你有机会发布Lambda函数吗? - samcorcos
我也很想看看这段代码:) - Marius Schmidt
我很好奇这是如何工作的。您可以指出是否有要点或其他文件? - NateTallman
干得好。我试图删除我们公司特定的代码,我希望它仍然有效: jsfiddle.net/g711p2jh - Render
在我们的例子中,只有某些目录/ xxx /正在被处理。 Root和其他目录将获取带有静态元数据字段的静态index.html文件。 - Render


您可以使用Lambda @ Edge配置CloudFront以将爬网程序HTTP请求直接发送到prerender.io。

基本思想是有一个查看器请求处理程序,它为应该发送到prerender.io的请求设置自定义HTTP头。例如,这个Lambda @ Edge代码:

        'use strict';
        /* change the version number below whenever this code is modified */
        exports.handler = (event, context, callback) => {
            const request = event.Records[0].cf.request;
            const headers = request.headers;
            const user_agent = headers['user-agent'];
            const host = headers['host'];
            if (user_agent && host) {
              if (/baiduspider|Facebot|facebookexternalhit|twitterbot|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator/.test(user_agent[0].value)) {
                headers['x-prerender-token'] = [{ key: 'X-Prerender-Token', value: '${PrerenderToken}'}];
                headers['x-prerender-host'] = [{ key: 'X-Prerender-Host', value: host[0].value}];
              }
            }
            callback(null, request);
        };

必须将Cloudfront分发配置为通过X-Prerender-Host和X-Prerender-Token标头。

最后,如果存在X-Prerender-Token,则origin-request处理程序会更改原始服务器:

      'use strict';
      /* change the version number below whenever this code is modified */
      exports.handler = (event, context, callback) => {
           const request = event.Records[0].cf.request;
           if (request.headers['x-prerender-token'] && request.headers['x-prerender-host']) {
             request.origin = {
                 custom: {
                     domainName: 'service.prerender.io',
                     port: 443,
                     protocol: 'https',
                     readTimeout: 20,
                     keepaliveTimeout: 5,
                     customHeaders: {},
                     sslProtocols: ['TLSv1', 'TLSv1.1'],
                     path: '/https%3A%2F%2F' + request.headers['x-prerender-host'][0].value
                 }
             };
          }
          callback(null, request);
      };

有一个完整的例子: https://github.com/jinty/prerender-cloudfront


1
2018-02-08 15:46



虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面发生更改,则仅链接答案可能会变为无效。 - 来自评论 - Daniel Grim


看看这里的完整解决方案,用咕噜声创建您网站的快照,并将其提供给只有亚马逊S3的搜索引擎:

用于静态网页的AngularJS SEO(S3 CDN)


0
2018-06-12 13:28