Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript &引用;单页“;JS网站与搜索引擎优化_Javascript_Seo_Backbone.js_Pushstate_Singlepage - Fatal编程技术网

Javascript &引用;单页“;JS网站与搜索引擎优化

Javascript &引用;单页“;JS网站与搜索引擎优化,javascript,seo,backbone.js,pushstate,singlepage,Javascript,Seo,Backbone.js,Pushstate,Singlepage,现在有很多很酷的工具来创建强大的“单页”JavaScript网站。在我看来,让服务器充当API(仅此而已)并让客户机处理所有HTML生成内容是正确的。这种“模式”的问题在于缺乏搜索引擎支持。我可以想出两种解决办法: 当用户进入网站时,让服务器完全按照客户端在导航时的方式呈现页面。所以如果我去http://example.com/my_path如果我通过pushState转到/my_path,服务器将直接呈现与客户端相同的内容 让服务器只为搜索引擎机器人提供一个特殊的网站。如果普通用户访问http

现在有很多很酷的工具来创建强大的“单页”JavaScript网站。在我看来,让服务器充当API(仅此而已)并让客户机处理所有HTML生成内容是正确的。这种“模式”的问题在于缺乏搜索引擎支持。我可以想出两种解决办法:

  • 当用户进入网站时,让服务器完全按照客户端在导航时的方式呈现页面。所以如果我去
    http://example.com/my_path
    如果我通过pushState转到
    /my_path
    ,服务器将直接呈现与客户端相同的内容
  • 让服务器只为搜索引擎机器人提供一个特殊的网站。如果普通用户访问
    http://example.com/my_path
    服务器应该给他一个JavaScript版本的网站。但是如果谷歌机器人访问,服务器应该给它一些最小的HTML,其中包含我希望谷歌索引的内容
  • 进一步讨论了第一种解决方案。我一直在一个网站上做这件事,这不是一个很好的经验。它不是干的,在我的例子中,我不得不为客户端和服务器使用两个不同的模板引擎

    我想我已经看到了一些好的ol'Flash网站的第二种解决方案。与第一种方法相比,我更喜欢这种方法,在服务器上使用正确的工具,可以轻松完成

    所以我真正想知道的是:

    • 你能想出更好的解决办法吗
    • 第二种解决方案的缺点是什么?如果谷歌以某种方式发现我没有像普通用户一样为谷歌机器人提供完全相同的内容,我会在搜索结果中受到惩罚吗

    从稍微不同的角度来看,您的第二个解决方案在可访问性方面是正确的。您将为无法使用javascript的用户(具有屏幕阅读器的用户等)提供替代内容

    这将自动增加搜索引擎优化的好处,在我看来,不会被谷歌视为一种“顽皮”的技术。

    我认为你需要这个:

    您还可以安装一个特殊的后端,通过在服务器上运行javascript来“呈现”您的页面,然后将其提供给google

    将这两种方法结合起来,就可以得到一个解决方案,而无需两次编程。(只要你的应用程序可以通过锚定片段完全控制。)

    虽然#2对开发者来说可能“更容易”,但它只提供搜索引擎抓取功能。是的,如果谷歌发现你提供不同的内容,你可能会受到惩罚(我不是这方面的专家,但我听说过这种情况)

    SEO和可访问性(不仅仅针对残疾人,还包括通过移动设备、触摸屏设备和其他非标准计算/互联网平台的可访问性)都有一个相似的基本理念:语义丰富的标记是“可访问的”(即可以访问、查看、阅读、处理或以其他方式使用)所有这些不同的浏览器。屏幕阅读器、搜索引擎爬虫或启用JavaScript的用户都应该能够毫无疑问地使用/索引/理解站点的核心功能

    根据我的经验,
    pushState
    不会增加这个负担。它只会将过去的事后思考和“如果我们有时间”带到web开发的前沿

    选项1中描述的内容通常是最好的方法,但是,与其他可访问性和SEO问题一样,在JavaScript应用程序中使用
    pushState
    进行此操作需要预先规划,否则将成为一个沉重的负担。它应该从一开始就嵌入到页面和应用程序体系结构中——改装是痛苦的,并且会导致更多的重复

    我最近一直在为几个不同的应用程序使用
    pushState
    和SEO,我发现我认为这是一个很好的方法。它基本上遵循您的条目#1,但不会复制html/模板

    大部分信息可在以下两篇博文中找到:

    其要点是,我使用ERB或HAML模板(运行Ruby on Rails、Sinatra等)进行服务器端渲染,创建主干网可以使用的客户端模板,以及Jasmine JavaScript规范。这就减少了服务器端和客户端之间标记的重复

    从这里开始,您需要采取一些额外的步骤,让JavaScript处理由服务器呈现的HTML—真正的渐进增强;获取交付的语义标记,并使用JavaScript对其进行增强

    例如,我正在使用
    pushState
    构建一个图像库应用程序。如果您从服务器请求
    /images/1
    ,它将在服务器上呈现整个图像库,并将所有HTML、CSS和JavaScript发送到浏览器。如果禁用了JavaScript,它将工作得非常好。您执行的每个操作都将从服务器请求不同的URL,服务器将为您的浏览器呈现所有标记。但是,如果启用了JavaScript,JavaScript将获取已经呈现的HTML以及服务器生成的一些变量,并从中接管

    下面是一个例子:

    <form id="foo">
      Name: <input id="name"><button id="say">Say My Name!</button>
    </form>
    
    这是一个非常简单的例子,但我认为它能说明问题

    当我在页面加载后实例化视图时,我将把服务器呈现的表单的现有内容作为视图的
    el
    提供给视图实例。当加载第一个视图时,我没有调用render或让视图为我生成
    el
    。我有一个渲染方法,可以在视图启动并运行之后使用,页面都是JavaScript。这使我可以在以后需要时重新渲染视图

    使用JavaScript单击“说出我的名字”按钮
    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")
      });
    });
    
    <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>
    
    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();
    
    <%= render :partial => 'some_thingy', object: my_model %>
    
    <%= template_include_tag 'some_thingy' %>
    
    html = poirot.someThingy(my_model)
    
    resources :articles
    match "*path", "main#index"
    
    <div id="no-js">
      <h1><%= @article.title %></h1>
      <p><%= @article.description %></p>
      <p><%= @article.content %></p>
    </div>
    
    $("#no-js").remove() # jQuery