"单页" JS网站和搜索引擎优化 [英] "Single-page" JS websites and SEO

查看:130
本文介绍了"单页" JS网站和搜索引擎优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有很多时下为使强大的单页网站的JavaScript工具凉。在我看来,这是通过让服务器作为一个API(仅此而已),并让客户端处理所有的HTML生成的东西做的权利。这个模式问题是缺乏搜索引擎支持。我能想到的两个解决方案:

There are a lot of cool tools for making powerful "single-page" JavaScript websites nowadays. In my opinion, this is done right by letting the server act as an API (and nothing more) and letting the client handle all of the HTML generation stuff. The problem with this "pattern" is the lack of search engine support. I can think of two solutions:


  1. 当用户进入该网站,让服务器呈现页面正好作为客户端会根据导航。所以,如果我去 http://example.com/my_path 服务器直接会使同样的事情,客户想如果我去 / my_path的通过pushState的。

  2. 让服务器只为搜索引擎机器人提供了一个专门的网站。如果一个普通用户访问 http://example.com/my_path 服务器应该给他的网站的一个JavaScript重的版本。但如果谷歌机器人访问,服务器应该给它一些最起码的HTML与我希望谷歌索引的内容。

  1. When the user enters the website, let the server render the page exactly as the client would upon navigation. So if I go to http://example.com/my_path directly the server would render the same thing as the client would if I go to /my_path through pushState.
  2. Let the server provide a special website only for the search engine bots. If a normal user visits http://example.com/my_path the server should give him a JavaScript heavy version of the website. But if the Google bot visits, the server should give it some minimal HTML with the content I want Google to index.

第一个解决方案进行了讨论进一步 href=\"http://stackoverflow.com/questions/6193858/pushstate-and-seo\">。我一直在网站上这样做的,它不是一个非常好的经验。这不是干燥,在我的情况,我不得不使用两种不同的模板引擎的客户端和服务器。

The first solution is discussed further here. I have been working on a website doing this and it's not a very nice experience. It's not DRY and in my case I had to use two different template engines for the client and the server.

我想我已经看到了一些好的醇'Flash网站的第二个解决方案。我喜欢这种方法比第一个,并与它可以相当怕疼完成的服务器上的合适的工具等等。

I think I have seen the second solution for some good ol' Flash websites. I like this approach much more than the first one and with the right tool on the server it could be done quite painlessly.

所以我真正想知道的是以下内容:

So what I'm really wondering is the following:


  • 您能想到的任何更好的解决方案?

  • 什么是与所述第二溶液的缺点是什么?如果谷歌在某些方面发现,我不是服务的谷歌机器人作为一个普通用户完全相同的内容,我会然后在搜索结果进行处罚?

推荐答案

尽管#2可能是作为一个开发者更容易对你来说,它只是提供了搜索引擎的抓取。是的,如果谷歌发现您提供不同的内容,你可能会被处罚(我不是这方面的专家,但我听说它发生的)。

While #2 might be "easier" for you as a developer, it only provides search engine crawling. And yes, if Google finds out your serving different content, you might be penalized (I'm not an expert on that, but I have heard of it happening).

这两个搜索引擎优化和可访问性(不只是为残疾人,但是通过移动设备访问性,触摸屏设备和其他非标计算/互联网启用平台)都具有相似的基本理念:语义丰富的标记是平易近人 (即可以被访问,查看,读取,加工处理,或以其他方式使用)对所有这些不同的浏览器。屏幕阅读器,搜索引擎爬虫或JavaScript的用户启用,都应该能够使用/索引/了解您网站的核心功能没有问题。

Both SEO and accessibility (not just for disabled person, but accessibility via mobile devices, touch screen devices, and other non-standard computing / internet enabled platforms) both have a similar underlying philosophy: semantically rich markup that is "accessible" (i.e. can be accessed, viewed, read, processed, or otherwise used) to all these different browsers. A screen reader, a search engine crawler or a user with JavaScript enabled, should all be able to use/index/understand your site's core functionality without issue.

pushState的不会增加这方面的负担,以我的经验。它不仅带来了曾经被认为是一种事后和如果我们有时间Web开发的最前沿。

pushState does not add to this burden, in my experience. It only brings what used to be an afterthought and "if we have time" to the forefront of web development.

你的描述选项#1通常是最好的方式去 - 但是,像其他辅助功能和搜索引擎优化的问题,在JavaScript重应用与 pushState的操作需要前期规划或将成为一个显著的负担。应该烤从一开始的页面和应用架构 - 改造是痛苦的,会造成更多的重复数据删除比是必要的。

What your describe in option #1 is usually the best way to go - but, like other accessibility and SEO issues, doing this with pushState in a JavaScript-heavy app requires up-front planning or it will become a significant burden. It should be baked in to the page and application architecture from the start - retrofitting is painful and will cause more duplication than is necessary.

我一直使用 pushState的和SEO最近的一对夫妇不同的应用,我发现了什么,我认为是一个很好的办法。它基本上跟随你的项目#1,但占不重复的HTML /模板。

I've been working with pushState and SEO recently for a couple of different application, and I found what I think is a good approach. It basically follows your item #1, but accounts for not duplicating html / templates.

大部分的信息都可以在这两个博客文章中找到:

Most of the info can be found in these two blog posts:

<一个href=\"http://lostechies.com/derickbailey/2011/09/06/test-driving-backbone-views-with-jquery-templates-the-jasmine-gem-and-jasmine-jquery/\">http://lostechies.com/derickbailey/2011/09/06/test-driving-backbone-views-with-jquery-templates-the-jasmine-gem-and-jasmine-jquery/

<一个href=\"http://lostechies.com/derickbailey/2011/06/22/rendering-a-rails-partial-as-a-jquery-template/\">http://lostechies.com/derickbailey/2011/06/22/rendering-a-rails-partial-as-a-jquery-template/

它的要点是,我使用ERB或HAML模板(运行Ruby on Rails的,西纳特拉等)对我的服务器端渲染和创建骨干可以使用客户端模板,以及为我的茉莉花的JavaScript规范。这削减了服务器端和客户端之间的标记的重复。

The gist of it is that I use ERB or HAML templates (running Ruby on Rails, Sinatra, etc) for my server side render and to create the client side templates that Backbone can use, as well as for my Jasmine JavaScript specs. This cuts out the duplication of markup between the server side and the client side.

从那里,你需要采取一些额外的步骤,以有一个由服务器呈现的HTML你的JavaScript的工作 - 真正的逐行增强;采取这一得到交付的语义标记,并用JavaScript增强了。

From there, you need to take a few additional steps to have your JavaScript work with the HTML that is rendered by the server - true progressive enhancement; taking the semantic markup that got delivered and enhancing it with JavaScript.

例如,我建设有 pushState的图片库的应用程序。如果您要求 /图像/ 1 从服务器,它将呈现在服务器上的整个图片库和发送所有的HTML,CSS的和JavaScript到您的浏览器。如果你禁用了JavaScript,它会完全正常工作。你采取的每一个动作都会从服务器请求一个不同的URL,服务器将呈现所有标记为你的浏览器。如果您启用JavaScript,虽然,JavaScript就拿起早已呈现的HTML由服务器生成的几个变量一起,并从那里接管。

For example, i'm building an image gallery application with pushState. If you request /images/1 from the server, it will render the entire image gallery on the server and send all of the HTML, CSS and JavaScript down to your browser. If you have JavaScript disabled, it will work perfectly fine. Every action you take will request a different URL from the server and the server will render all of the markup for your browser. If you have JavaScript enabled, though, the JavaScript will pick up the already rendered HTML along with a few variables generated by the server and take over from there.

下面是一个例子:

<form id="foo">
  Name: <input id="name"><button id="say">Say My Name!</button>
</form>

服务器呈现此之后,由JavaScript将它捡起(使用在此例的Backbone.js的视图)

After the server renders this, the JavaScript would pick it up (using a Backbone.js view in this example)

FooView = Backbone.View.extend({
  events: {
    "change #name": "setName",
    "click #say": "sayName"
  },

  setName: function(e){
    var name = $(e.currentTarget).val();
    this.model.set({name: name});
  },

  sayName: function(e){
    e.preventDefault();
    var name = this.model.get("name");
    alert("Hello " + name);
  },

  render: function(){
    // do some rendering here, for when this is just running JavaScript
  }
});

$(function(){
  var model = new MyModel();
  var view = new FooView({
    model: model,
    el: $("#foo")
  });
});

这是一个很简单的例子,但我认为它会在整个点。

This is a very simple example, but I think it gets the point across.

当我instante在页面加载后的看法,我认为提供由服务器呈现的形式存在的内容,到视图实例作为该视图。我的的调用render或有视图生成一个对我来说,第一个视图加载时。我有一个可用的渲染方法后视图启动并运行和页面是所有的JavaScript。这让我以后重新渲染视图,如果我需要。

When I instante the view after the page loads, I'm providing the existing content of the form that was rendered by the server, to the view instance as the el for the view. I am not calling render or having the view generate an el for me, when the first view is loaded. I have a render method available for after the view is up and running and the page is all JavaScript. This lets me re-render the view later if I need to.

点击说我的名字用JavaScript按钮启用将导致一个警告框。没有JavaScript,它会回发到服务器,服务器可能使名义某处的HTML元素。

Clicking the "Say My Name" button with JavaScript enabled will cause an alert box. Without JavaScript, it would post back to the server and the server could render the name to an html element somewhere.

修改

考虑一个更复杂的例子,你有一个需要连接(从下面这个评论)名单

Consider a more complex example, where you have a list that needs to be attached (from the comments below this)

假设你有用户在&LT名单; UL&GT; 标记。这份名单由渲染服务器时,浏览器提出的要求,结果看起来是这样的:

Say you have a list of users in a <ul> tag. This list was rendered by the server when the browser made a request, and the result looks something like:

<ul id="user-list">
  <li data-id="1">Bob
  <li data-id="2">Mary
  <li data-id="3">Frank
  <li data-id="4">Jane
</ul>

现在你通过这个列表需要循环并附加骨干视图和模型每个&LT的;李&GT; 项目。与使用数据-ID 属性,可以发现每个标签来自易模型。那么你就需要一个集合视图和项目视图是足够聪明的自身附加到这个网站。

Now you need to loop through this list and attach a Backbone view and model to each of the <li> items. With the use of the data-id attribute, you can find the model that each tag comes from easily. You'll then need a collection view and item view that is smart enough to attach itself to this html.

UserListView = Backbone.View.extend({
  attach: function(){
    this.el = $("#user-list");
    this.$("li").each(function(index){
      var userEl = $(this);
      var id = userEl.attr("data-id");
      var user = this.collection.get(id);
      new UserView({
        model: user,
        el: userEl
      });
    });
  }
});

UserView = Backbone.View.extend({
  initialize: function(){
    this.model.bind("change:name", this.updateName, this);
  },

  updateName: function(model, val){
    this.el.text(val);
  }
});

var userData = {...};
var userList = new UserCollection(userData);
var userListView = new UserListView({collection: userList});
userListView.attach();

在这个例子中, UserListView 将遍历所有的&LT的;李&GT; 标记并附加一个视图与每一个正确的模型对象。它设置为模型的名称更改事件的事件处理程序和更新时出现改变的元素显示的文本。

In this example, the UserListView will loop through all of the <li> tags and attach a view object with the correct model for each one. it sets up an event handler for the model's name change event and updates the displayed text of the element when a change occurs.

这样的过程,采取服务器呈现的HTML,并有我的JavaScript接管并运行它,是一个伟大的方式把事情滚动的搜索引擎优化,辅助功能, pushState的的支持。

This kind of process, to take the html that the server rendered and have my JavaScript take over and run it, is a great way to get things rolling for SEO, Accessibility, and pushState support.

希望有所帮助。

这篇关于&QUOT;单页&QUOT; JS网站和搜索引擎优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆