- 我有使用Backbone.js构建的单页面应用程序。
- 我在Amazon S3上托管应用程序(应用程序仅包含静态文件)。
- 我使用CloudFront作为Bucket CDN。
- 应用程序访问
https://myapp.com -> https://abcdefgh34545.cloudfront.com -> https://myBucket.s3-eu-west-1.amazonaws.com/index.html
我怎么用 Prerender.io
用这个堆栈服务?我必须以某种方式检测WebSpider / WebRobot正在访问该页面并将其重定向到prerender.io ...
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。
我设法通过不使用Prerender但创建AWS Lambda函数来实现这一点:
- 从CloudFront请求原始页面(它实际上始终是相同的index.html)
- 通过API Gateway catch-all代理映射lambda函数
- 研究路径并弄清楚应该是什么资源页面(在我的例子中它只是/ user / {name},所以我只需要做一个用例
- 发出REST API请求以获取用户的动态数据
- 正则表达式用动态元字段替换现有的元字段
- 使用新的metas返回新的索引文件
配置新原点(新lambda函数)和行为(map / user / *请求到这个新原点)。请确保对源使用“仅HTTPS”原始协议策略,因为API网关仅为HTTPS,此处重定向将导致主机名更改。
(如果您偶然使用了重定向,那么您将需要Invalidate“/ *”,因为一些CloudFront错误,配置更改将无济于事;我花了几个小时调试这个昨晚)
您可以使用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
看看这里的完整解决方案,用咕噜声创建您网站的快照,并将其提供给只有亚马逊S3的搜索引擎:
用于静态网页的AngularJS SEO(S3 CDN)