Angularjs 使用AmazonS3时,如何将爬虫请求重定向到预呈现页面? 问题

Angularjs 使用AmazonS3时,如何将爬虫请求重定向到预呈现页面? 问题,angularjs,amazon-web-services,amazon-s3,seo,single-page-application,Angularjs,Amazon Web Services,Amazon S3,Seo,Single Page Application,我有一个静态SPA网站,用Angular构建,托管在AmazonS3上。我试图让爬虫能够访问我的预呈现页面,但我无法重定向爬虫请求,因为AmazonS3不提供URL重写选项,并且重定向规则有限 我所拥有的 我已将以下元标记添加到我的index.html页面的: 此外,我的SPA在HTML5推送状态下使用了漂亮的URL(没有hash#符号) 使用此设置,当爬虫找到我的http://mywebsite.com/about链接,它将向http://mywebsite.com/about?_esca

我有一个静态SPA网站,用Angular构建,托管在AmazonS3上。我试图让爬虫能够访问我的预呈现页面,但我无法重定向爬虫请求,因为AmazonS3不提供URL重写选项,并且重定向规则有限

我所拥有的 我已将以下元标记添加到我的index.html页面的


此外,我的SPA在HTML5推送状态下使用了漂亮的URL(没有hash
#
符号)

使用此设置,当爬虫找到我的
http://mywebsite.com/about
链接,它将向
http://mywebsite.com/about?_escaped_fragment_=
。这是一个由其他爬虫跟随的爬虫

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

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

location / {
  if ($args ~ "_escaped_fragment_=") { 
    rewrite ^/(.*)$ /snapshots/$1.html break; 
  } 
} 
但在AmazonS3中,我受到基于键前缀和HttpErrorCodes的限制。
?\u转义\u片段\u=
不是键前缀,因为它出现在URL的末尾,并且不会给出HTTP错误,因为Angular将忽略它

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

对于AmazonS3,我必须遵守它们的重定向规则

我已经设法让它在一个丑陋的解决方法下工作。如果我为每个页面创建一个新规则,我就完成了:


关于?你逃走了_=
我的网站
快照/about.html
正如您在这个解决方案中看到的,每个页面都需要自己的规则。由于Amazon只限制了50条重定向规则,因此这不是一个可行的解决方案

另一个解决方案是忘记漂亮的URL,使用hashbang。有了这个,我的链接将是
http://mywebsite.com/#!关于
,爬虫将使用
http://mywebsite.com/?_escaped_fragment_=about
。由于URL将以
?\u转义\u片段\u=
开头,因此可以使用KeyPrefix捕获它,只需一条重定向规则就足够了。然而,我不想使用丑陋的URL

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

简短回答 AmazonS3(和AmazonCloudFront)不提供重写规则,只有有限的重定向选项。但是,您不需要重定向或重写URL请求。只需预先渲染所有HTML文件,然后按照网站路径上传它们即可

由于浏览网页的用户启用了JavaScript,Angular将被触发并控制页面,从而重新呈现模板。这样,所有角度功能都可供该用户使用

关于爬虫,预先呈现的页面就足够了


例子 如果您有一个名为www.myblog.com的网站,以及一个指向另一个页面的链接,该页面的URL为www.myblog.com/posts/my first post。您的Angular应用程序可能具有以下结构:根目录中的index.html文件,负责所有内容。页面我的第一篇文章是一个部分HTML文件,位于/partials/my first post.HTML

这种情况下的解决方案是在部署时使用预渲染工具。您可以使用它,但不能使用这样的中间件工具,因为您有一个托管在AmazonS3中的静态站点

您需要使用此预渲染工具创建两个文件:index.htmlmy first post。请注意,我的第一篇文章将是一个没有扩展名.HTML的HTML文件,但是当您上传到Amazon S3时,需要将其内容类型设置为text/HTML

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

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


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

我所说的根路径是指:


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



编辑: 下面是我使用PhantomJS预渲染页面时使用的一个小JavaScript代码。在安装PhantomJS并使用单个页面测试脚本之后,在部署站点之前,向构建过程中添加一个脚本以预呈现所有页面

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,但不是。它必须使用幻影可执行文件而不是节点来执行。

我刚写完问题,就意识到如何解决这个问题。由于我花了很多时间试图通过一条错误的路径来解决这个问题,我在下面发布了我的答案,希望能帮助其他人。如果有一个脚本可以帮助预渲染,那就太棒了。@jjbskir,我已经添加了我用来预渲染一个页面的脚本。这太酷了!我可以看到这对我的一些项目有效,但对其他项目无效。我的项目只有静态html,没有太多的交互性,但我动态添加到视图和控制器中的项目会出现问题。这个周末我开始在wa上工作