用于静态网页的AngularJS SEO(S3 CDN)

adv*_*013 27 javascript seo amazon-s3 amazon-web-services angularjs

我一直在研究如何改进托管在像Amazon S3这样的CDN上的angularJS应用程序的SEO(即没有后端的简单存储).大多数解决方案,PhantomJS,prerender.io,seo.js等依赖于后端来识别?_escaped_fragment_爬虫生成的URL,然后从其他地方获取相关页面.即使您提前生成快照页,即使是grunt-html-snapshot也最终需要您这样做.

解决方案基本上依赖于使用cloudflare作为反向代理,这看起来有点浪费,因为他们的服务提供的大多数安全设备等对于静态站点来说是完全冗余的.根据这里的建议设置反向代理也似乎有问题,因为它需要i)路由所有AngularJS应用程序我需要静态html通过一个代理服务器可能会妨碍性能或ii)为每个应用程序设置一个单独的代理服务器在这一点上,我也可以建立一个后端,这在我工作的规模上是不可承受的.

无论如何这样做,或者是静态托管AngularJS应用程序与伟大的SEO基本上不可能,直到谷歌更新他们的爬虫?


在John Conde的评论之后转发给网站管理员.

Rob*_*ool 2

以下是如何在 S3 等存储服务上使您的应用程序 SEO 友好的完整概述,其中包含漂亮的 url(无 #)以及 grunt 的所有内容,并在构建后执行简单的命令:

grunt seo
Run Code Online (Sandbox Code Playgroud)

这仍然是一个解决方法的难题,但它正在发挥作用,而且是你能做的最好的事情。感谢@ericluwj 和他的博文给了我启发。

概述

目标和 url 结构

目标是在 Angular 应用程序中为每个状态创建 1 个 html 文件。唯一的主要假设是您使用 html5history 从 url 中删除“#”(您应该这样做!)并且所有路径都是绝对路径或使用角度状态。有很多帖子解释了如何做到这一点。

网址以斜杠结尾,如下所示 http://yourdomain.com/page1/

就我个人而言,我确保http://yourdomain.com/page1没有尾部斜杠)也到达其目的地,但这不是这里的主题。我还确保每种语言都有不同的状态和不同的 url。

SEO逻辑

我们的目标是当有人通过 http 请求访问您的网站时:

  • 如果是搜索引擎爬虫:让他停留在包含所需html的页面上。该页面还包含角度逻辑(例如启动您的应用程序),但爬虫无法读取该逻辑,因此他故意坚持使用您为他提供的 html 并将其编入索引。
  • 对于普通人和智能机器:确保 Angular 被激活,删除生成的 html 并正常启动您的应用程序

咕噜任务

我们来完成一些繁琐的任务:

  //grunt plugins you will need:
  grunt.loadNpmTasks('grunt-prerender');
  grunt.loadNpmTasks('grunt-replace');
  grunt.loadNpmTasks('grunt-wait');
  grunt.loadNpmTasks('grunt-aws-s3');

  //The grunt tasks in the right order
  grunt.registerTask('seo', 'First launch server, then prerender and replace', function (target) {
    grunt.task.run([
      'concurrent:seo' //Step 1: in parrallel launch server, then perform so-called seotasks
    ]);
  });

  grunt.registerTask('seotasks', [
    'http', //This is an API call to get all pages on my website. Skipping this step in this tutorial.
    'wait', // wait 1.5 sec to make sure that server is launched
    'prerender', //Step 2: create a snapshot of your website
    'replace', //Step 3: clean the mess
    'sitemap', //Create a sitemap of your production environment
    'aws_s3:dev' //Step 4: upload
  ]);
Run Code Online (Sandbox Code Playgroud)

第 1 步:使用并发启动本地服务器:seo

我们首先需要启动一个本地服务器(例如 gruntserve),以便我们可以拍摄网站的快照。

//grunt config
concurrent: {
  seo: [
    'connect:dist:keepalive', //Launching a server and keeping it alive
    'seotasks' //now that we have a running server we can launch the SEO tasks
  ]
}
Run Code Online (Sandbox Code Playgroud)

第 2 步:使用 grunt prerender 创建网站快照

grunt-prerender 插件允许您使用 PhantomJS 拍摄任何网站的快照。在我们的例子中,我们想要拍摄我们刚刚启动的本地主机网站的所有页面的快照。

//grunt config
prerender: {
  options: {
    sitePath: 'http://localhost:9001', //points to the url of the server you just launched. You can also make it point to your production website.
    //As you can see the source urls allow for multiple languages provided you have different states for different languages (see note below for that)
    urls: ['/', '/projects/', '/portal/','/en/', '/projects/en/', '/portal/en/','/fr/', '/projects/fr/', '/portal/fr/'],//this var can be dynamically updated, which is done in my case in the callback of the http task
    hashed: true,
    dest: 'dist/SEO/',//where your static html files will be stored
    timeout:5000,
    interval:5000, //taking a snapshot of how the page looks like after 5 seconds.
    phantomScript:'basic',
    limit:7 //# pages processed simultaneously 
  }
}
Run Code Online (Sandbox Code Playgroud)

第 3 步:使用 grunt Replace 清理混乱

如果您打开预渲染的文件,它们将适用于爬虫,但不适用于人类。对于使用 Chrome 的人来说,您的指令将加载两次。因此,您需要在Angular 激活之前(即在 head 之后)将智能浏览器重定向到您的主页。

//Add the script tag to redirect if we're not a search bot
replace: {
  dist: {
    options: {
      patterns: [
        {
          match: '<head>',
          //redirect to a clean page if not a bot (to your index.html at the root basically).
          replacement: '<head><script>if(!/bot|googlebot|crawler|spider|robot|crawling/i.test(navigator.userAgent)) { document.location = "/#" + window.location.pathname; }</script>'
          //note: your hashbang (#) will still work.
        }
      ],
      usePrefix: false
    },
    files: [
      {expand: true, flatten: false, src: ['dist/SEO/*/**/*.html'], dest: ''} 
    ]
  }
Run Code Online (Sandbox Code Playgroud)

还要确保您的 ui-view 元素上的 index.html 中有此代码,这会在 Angular 启动之前清除所有生成的 html 指令。

<div ui-view autoscroll="true" id="ui-view"></div>

<!-- this script is needed to clear ui-view BEFORE angular starts to remove the static html that has been generated for search engines who cannot read angular -->
<script> 
  if(!/bot|googlebot|crawler|spider|robot|crawling/i.test( navigator.userAgent)) { document.getElementById('ui-view').innerHTML = ""; }
</script>
Run Code Online (Sandbox Code Playgroud)

第4步:上传到aws

您首先上传包含您的构建的 dist 文件夹。然后,您可以使用预渲染和更新的文件覆盖它。

aws_s3: {
  options: {
    accessKeyId: "<%= aws.accessKeyId %>", // Use the variables
    secretAccessKey: "<%= aws.secret %>", // You can also use env variables
    region: 'eu-west-1',
    uploadConcurrency: 5, // 5 simultaneous uploads
  },
  dev: {
    options: {
      bucket: 'xxxxxxxx'
    },
    files: [
      {expand: true, cwd: 'dist/', src: ['**'], exclude: 'SEO/**', dest: '', differential: true},
      {expand: true, cwd: 'dist/SEO/', src: ['**'], dest: '', differential: true},
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

就是这样,你就有了解决方案!人类和机器人都将能够读取您的网络应用程序