首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在使用亚马逊S3时将爬虫请求重定向到预呈现的页面?

如何在使用亚马逊S3时将爬虫请求重定向到预呈现的页面?
EN

Stack Overflow用户
提问于 2015-09-07 00:01:44
回答 1查看 3K关注 0票数 6

问题

我有一个静态的SPA网站构建的角度,并托管在亚马逊S3。我试图让爬虫可以访问我的预渲染页面,但是我不能重定向爬虫请求,因为Amazon没有提供S3重写选项,而且重定向规则是有限的。

我所拥有的

我向<head> of index.html页面添加了以下元标记:

代码语言:javascript
运行
复制
<meta name="fragment" content="!">

另外,我的SPA使用了带有#推送状态的漂亮URL(没有散列HTML5符号)。

使用此设置,当爬虫找到我的http://mywebsite.com/about链接时,它将向http://mywebsite.com/about?_escaped_fragment_=发出一个GET请求。这是一个Google定义的模式,其他爬虫紧随其后。

我需要的是用about.html文件的预呈现版本来回答这个请求。我已经用Phantom.js完成了这个预呈现,但是我不能为爬虫提供正确的文件,因为S3没有重写规则。

nginx服务器中,解决方案是添加如下重写规则:

代码语言:javascript
运行
复制
location / {
  if ($args ~ "_escaped_fragment_=") { 
    rewrite ^/(.*)$ /snapshots/$1.html break; 
  } 
} 

但在亚马逊S3,我受到基于KeyPrefixes和HttpErrorCodes的重定向规则的限制。?_escaped_fragment_=不是KeyPrefix,因为它出现在URL的末尾,而且它不会产生HTTP错误,因为角将忽略它。

我试过的

我已经开始尝试在ngRoute中使用动态模板,但是后来我意识到我不能用任何角度的解决方案来解决这个问题,因为我的目标是无法执行JavaScript的爬虫。

对于亚马逊S3,我必须坚持他们的重定向规则。

我设法用一个丑陋的方法解决了这个问题。如果我为每一页创建了一个新规则,那么我就完成了:

代码语言:javascript
运行
复制
<RoutingRules>

  <!-- each page needs it own rule -->
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>about?_escaped_fragment_=</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <HostName>mywebsite.com</HostName>
      <ReplaceKeyPrefixWith>snapshots/about.html</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>

</RoutingRules>

正如您在这个解决方案中所看到的,每个页面都需要自己的规则。由于Amazon只限制了50条重定向规则,这不是一个可行的解决方案。

另一个解决方案是忘记漂亮的URL并使用hashbang。有了这个链接,我的链接将是http://mywebsite.com/#!about,爬虫将使用http://mywebsite.com/?_escaped_fragment_=about请求此链接。因为URL将以?_escaped_fragment_=开头,所以可以使用KeyPrefix捕获它,只要一个重定向规则就足够了。但是,我不想使用丑陋的URL。

那么,我如何在亚马逊 S3中拥有一个静态SPA,并且对SEO友好呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-07 00:01:44

简短回答

亚马逊S3 (和亚马逊CloudFront)不提供重写规则,只有有限的重定向选项。但是,您不需要重定向或重写您的请求。只需预渲染所有的 HTML文件和上传它们遵循您的网站路径

由于用户浏览网页已经启用JavaScript,角形将被触发,并将控制页面,这将导致重新呈现的模板。有了这个功能,所有的角度功能都将提供给这个用户。

关于爬虫,预渲染的页面就足够了。

示例

如果您有一个名为www.myblog.com的网站,并且有一个链接到另一个带有URL www.myblog.com/posts/my-first-post.的页面可能,您的角应用程序有以下结构:根目录中的index.html文件,它负责所有事情。页my-first-post是位于/partials/my-first-post.html.中的部分HTML文件。

在这种情况下,解决方案是在部署时使用预呈现工具。您可以为此使用PhantomJS,但是不能使用像普莱伦德这样的中间件工具,因为您有一个驻留在AmazonS3中的静态站点。

您需要使用这个预呈现工具来创建两个文件:index.html和index.html。请注意,my-first-post将是一个没有.html扩展名的HTML文件,但是您需要在上传到AmazonS3时将其内容类型设置为text/html

您将将my-first-post index.html文件放置在根目录中,并将其放置在名为posts的文件夹中,以与URL路径匹配。

使用这种方法,爬虫将能够检索您的HTML文件,用户将乐于使用所有的角度功能。

注释:此解决方案要求使用根路径引用所有文件。如果您访问链接www.myblog.com/posts/my-first-post.,相对路径将无法工作。

根路径,我的意思是:

代码语言:javascript
运行
复制
<script src="/js/myfile.js"></script>

使用相对路径的错误方式是:

代码语言:javascript
运行
复制
<script src="js/myfile.js"></script>

编辑:

下面是一个小的JavaScript代码,我用它来预录制使用PhantomJS的页面。在安装PhantomJS并使用单个页面测试脚本之后,在构建过程中添加一个脚本,以便在部署站点之前预先录制所有页面。

代码语言:javascript
运行
复制
var fs = require('fs');
var webPage = require('webpage');
var page = webPage.create();

// since this tool will run before your production deploy, 
// your target URL will be your dev/staging environment (localhost, in this example)
var path = 'pages/my-page';
var url = 'http://localhost/' + path;

page.open(url, function (status) {

  if (status != 'success')
    throw 'Error trying to prerender ' + url;

  var content = page.content;
  fs.write(path, content, 'w');

  console.log("The file was saved.");
  phantom.exit();
});

注意:它看起来像Node.js,但它不是。它必须使用幻影可执行文件而不是节点来执行。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32429488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档