angularjs – 如何在使用Amazon S3时将爬虫请求重定向到预渲染页
问题
我有一个使用Angular构建并在Amazon S3上托管的静态SPA站点.我正在尝试使爬网程序可以访问预呈现的页面,但由于Amazon S3不提供URL重写选项且重定向规则有限,因此我无法重定向爬网程序请求. 是)我有的 我已将以下元标记添加到< head>我的index.html页面: <meta name="fragment" content="!"> 此外,我的SPA使用漂亮的URL(没有哈希#符号)和HTML5推送状态. 通过此设置,当抓取工具找到我的http://mywebsite.com/about链接时,它会向http://mywebsite.com/about?_escaped_fragment_=发出GET请求.这是一个pattern defined by Google,其次是其他爬虫. 我需要的是使用about.html文件的预渲染版本来回答此请求.我已经使用Phantom.js完成了这个预渲染,但我无法向抓取工具提供正确的文件,因为Amazon S3没有重写规则. 在nginx服务器中,解决方案是添加重写规则,如: location / { if ($args ~ "_escaped_fragment_=") { rewrite ^/(.*)$/snapshots/$1.html break; } } 但在Amazon S3中,我受到基于KeyPrefixes和HttpErrorCodes的redirect rules的限制. ?_escaped_fragment_ =不是KeyPrefix,因为它出现在URL的末尾,并且它不会出现HTTP错误,因为Angular会忽略它. 我试过的 我开始尝试使用ngRoute的动态模板,但后来我意识到我无法使用任何Angular解决方案来解决这个问题,因为我的目标是无法执行JavaScript的抓取工具. 使用Amazon S3,我必须坚持使用重定向规则. 我已经成功地使用了一个丑陋的解决方法.如果我为每个页面创建一个新规则,我就完成了: <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> 正如您在此解决方案中所看到的,每个页面都需要自己的规则.由于亚马逊仅限于50个重定向规则,因此这不是一个可行的解决方案. 另一种解决方案是忘记漂亮的URL并使用hashbang.有了这个,我的链接将是http://mywebsite.com/#!about,爬虫将通过http://mywebsite.com/?_escaped_fragment_=about请求此链接.由于URL将以?_escaped_fragment_ =开头,因此可以使用KeyPrefix捕获它,只需一个重定向规则即可.但是,我不想使用丑陋的URL. 那么,我如何在Amazon S3中拥有静态SPA并且对SEO友好?
简答
Amazon S3(和Amazon CloudFront)不提供重写规则,只有有限的重定向选项.但是,您无需重定向或重写URL请求.只需预渲染所有HTML文件,然后按照您的网站路径上传它们. 由于浏览网页的用户启用了JavaScript,因此将触发Angular并控制页面,从而导致重新呈现模板.有了这个,所有Angular功能都将可供该用户使用. 关于爬虫,预渲染页面就足够了. 例 如果您有一个名为www.myblog.com的网站以及指向另一个网址的链接,其网址为www.myblog.com/posts/my-first-post.可能,您的Angular应用程序具有以下结构:index.html文件位于根目录中并负责所有内容.页面my-first-post是位于/partials/my-first-post.html中的部分HTML文件. 这种情况下的解决方案是在部署时使用预渲染工具.您可以使用PhantomJS,但不能使用像Prerender这样的中间件工具,因为您在Amazon S3中托管了一个静态站点. 您需要使用此预渲染工具来创建两个文件:index.html和my-first-post.请注意,my-first-post将是一个没有.html扩展名的HTML文件,但是当您上传到Amazon S3时,您需要将其Content-Type设置为text / html. 您将index.html文件放在根目录中,将my-first-post放在名为posts的文件夹中,以匹配您的URL路径/ posts / my-first-post. 使用这种方法,爬虫将能够检索您的HTML文件,用户将乐于使用所有Angular功能. 注意:此解决方案要求使用根路径引用所有文件.如果您访问链接www.myblog.com/posts/my-first-post,相对路径将不起作用. 根路径,我的意思是: <script src="/js/myfile.js"></script> 使用相对路径的错误方法是: <script src="js/myfile.js"></script> 编辑: 下面是一个小的JavaScript代码,我用它来使用PhantomJS预呈现页面.安装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,但事实并非如此.它必须使用Phantom可执行文件而不是Node执行. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- bootstrap3中container与container_fluid外层容器的区别讲解
- 如何使用Angularjs在本地存储中存储数据?
- AngularJS控制器controller通信方法
- Bootstrap twitter活动导航栏 – 使用JQuery更改类名
- 如何编写一个通过从shell运行来编译自己的程序?
- 在Scala中为隐式参数隐式转换通用容器
- BPEL研究(1):BPEL语言的基本特点
- scala – 如何使用Kryo反序列化不可变集合?
- twitter-bootstrap – 如何在Bootstrap中设置ScrollSpy的偏
- 为什么UNIX排序实用程序在没有选项-b的情况下忽略前导空格?