Single Page App + Amazon S3 + Amazon CloudFront + Prerender.io - 如何设置?

Posted

技术标签:

【中文标题】Single Page App + Amazon S3 + Amazon CloudFront + Prerender.io - 如何设置?【英文标题】:Single Page App + Amazon S3 + Amazon CloudFront + Prerender.io - how to set up? 【发布时间】:2014-04-18 11:02:07 【问题描述】:
    我有使用 Backbone.js 构建的单页应用程序。 我在 Amazon S3 上托管应用程序(应用程序仅包含静态文件)。 我使用 CloudFront 作为存储桶 CDN。 应用程序被https://myapp.com -> https://abcdefgh34545.cloudfront.com -> https://myBucket.s3-eu-west-1.amazonaws.com/index.html访问

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

【问题讨论】:

您不能将 cloudfront 配置为按请求的标头值缓存 html。基本上,您将通过标头确定请求是否来自机器人,并缓存该请求的预呈现版本和浏览器请求的非预呈现版本。 这是一个完整的答案,只有一个 grunt 命令:***.com/questions/23043336/… 【参考方案1】:

您可以使用 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);
        ;

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

如果存在 X-Prerender-Token,最后一个源请求处理程序会更改源服务器:

      '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

【讨论】:

为什么需要两个 Lambda?为什么单个 Lambda 不能更改原点设置 Prerender 标头? 如果我没记错的话,我认为这是因为不同的 lambda 具有不同的上下文,并且您在 origin-request lambda 中没有原始 url,但您在 viewer-request lambda 中有/跨度> 【参考方案2】:

我通过完全不使用 Prerender 而是创建了以下 AWS Lambda 函数来设法做到这一点:

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

配置新的来源(新的 lambda 函数)和行为(将 /user/* 请求映射到这个新的来源)。一定要对源使用“HTTPS only”源协议策略,因为API网关只有HTTPS,这里重定向会导致主机名发生变化。

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

【讨论】:

这是一个很好的解决方案!看起来这只有在September 2016 才有可能。您有机会发布 Lambda 函数吗? 我很好奇它是如何工作的。您可以指出要点或其他文档吗? 给你。我试图删除我们公司特定的代码,我希望它仍然有效:jsfiddle.net/g711p2jh 爱它。谢谢@Render 尝试一下。因此,您将 API 网关设置为仅捕获云端正在访问的特定端点上的所有请求? 在我们的例子中,只有某个目录 /xxx/ 被这样处理。根目录和其他目录将获得带有静态元数据字段的静态 index.html 文件。【参考方案3】:

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

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

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

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

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

【讨论】:

S3 支持数据的反向代理设置不是理想的解决方案,但它仅提供对 S3 文件的完全受控访问,具有缓存设施和 SPDY 等交付优化。 CloudFront 仅优化文件地理位置,但不优化传输速度(TCP 拥塞窗口和内核设置)。 我同意。这并不理想,但它是完全 S3 托管站点的唯一解决方案之一。 可以在web.archive.org/web/20140405234445/http://www.dave.cx/post/23/…找到已归档的博文【参考方案4】:

在这里查看完整的解决方案,使用 grunt 创建您网站的快照,并将它们提供给搜索引擎,只需要 amazon S3:

AngularJS SEO for static webpages (S3 CDN)

【讨论】:

【参考方案5】:

如前所述,似乎最简单的方法是配置 CloudFront/Lambda@Edge 以将请求代理到预呈现服务。我找到了一个似乎可以为您完成上述大量工作的存储库:https://github.com/sanfrancesco/prerendercloud-lambda-edge

这使用 Lambda@Edge 通过make deploy 命令预呈现您的应用程序。不幸的是,这使用了 prerender.cloud,而不是 prerender.io。希望这不是一个障碍。

【讨论】:

以上是关于Single Page App + Amazon S3 + Amazon CloudFront + Prerender.io - 如何设置?的主要内容,如果未能解决你的问题,请参考以下文章

Practise Site Home Sample Page Codes de carte cadeau Amazon | Codes Promo Amazon

单页应用(Single Page Application)的搜索引擎优化

网站建设单页应用(Single Page Application)的搜索引擎优化

如何在WordPress page.php,single.php中加载style.css根目录

html 来自http://wiki.jikexueyuan.com/project/kendo-ui-development-tutorial/the-layout-single-page-appl

html 来自http://wiki.jikexueyuan.com/project/kendo-ui-development-tutorial/the-view-single-page-applic