Одностраничное Приложение + Amazon S3 + Amazon CloudFront + Prerender.io-как настроить?

  1. у меня есть одностраничное приложение, построенное с магистралью.js.
  2. I host app (приложение состоит только из статических файлов) на Amazon S3.
  3. Я использую CloudFront как ведро CDN.
  4. приложение доступно по https://myapp.com -> https://abcdefgh34545.cloudfront.com -> https://myBucket.s3-eu-west-1.amazonaws.com/index.html

как я могу использовать Prerender.io сервис с этим стеком? Я должен каким-то образом обнаружить, что WebSpider/WebRobot обращается к странице и перенаправляет ее на prerender.Ио...

4 ответов


трудно использовать Prerender.io со статическим сайтом Amazon S3.

вы можете встать на сервер nginx / apache перед s3: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/

Дэвид смог создать статический HTML и сохранить их в S3, затем используйте CloudFlare для обнаружения _escaped_fragment_ в URL-адресе и перенаправьте его в статический HTML на S3.


мне удалось сделать это, не используя Prerender вообще, но создав функцию AWS Lambda, которая:

  • запрашивает исходную страницу из CloudFront (на самом деле это всегда один и тот же индекс.html)
  • сопоставьте лямбда-функцию через API Gateway catch-all proxy
  • изучите путь и выясните, какая страница ресурса должна быть (в моем случае это просто / user / {name}, поэтому мне нужно сделать только один вариант использования
  • сделать запрос REST API для получения динамических данных для пользователя
  • регулярное выражение замените существующие мета-поля динамическими
  • верните новый индексный файл с новыми metas

Настройка нового источника (новая лямбда-функция) и поведение (карта /пользователь/* запросы к этому новому источнику). Обязательно используйте политику протокола источника "только HTTPS" для источника, так как шлюз API-это только HTTPS, перенаправление здесь приведет к изменению имени хоста.

(Если вы случайно использовали редирект, то вам потребуется Invalidate "/ * " как из-за какой-то ошибки CloudFront изменение конфигурации не поможет ; я провел несколько часов отладки этой прошлой ночью)


Вы можете использовать Lambda@Edge для настройки CloudFront для отправки HTTP-запросов искателя непосредственно в prerender.Ио.

основная идея состоит в том, чтобы иметь обработчик запросов просмотра, который устанавливает пользовательский HTTP-заголовок для запросов, которые должны быть отправлены в prerender.Ио. Например, этот код 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:

      '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


посмотрите на полное решение здесь, создавая снимки вашего сайта с помощью grunt и обслуживая их в поисковых системах с помощью amazon S3:

AngularJS SEO для статических веб-страниц (S3 CDN)