如何在不刷新页面的情况下更改路由和内容? (机器人友好)

时间:2016-05-29 15:58:36

标签: javascript php jquery angularjs ajax

我想知道是否有可能更改网址显示并根据更改页面的内容并使网页的网址和内容与机器人友好(这意味着机器人可以实际索引它们)。

我已经尝试使用 AJAX 动态加载数据并使用 angularjs 路由,但机器人无法将其编入索引。

漂亮的网址查询字符串不是我正在寻找的,我正在寻找一种能够在着陆时呈现数据的理论在没有页面刷新的情况下更改链接点击的路径和内容,我不想编写代码两次(一次在服务器端,一次在前端)。

这些是我已经尝试过的事情,对此解决方案的任何帮助或指导都将不胜感激。

更新

没有依赖的所有语言的无库解决方案/结构将是最准确的答案!

5 个答案:

答案 0 :(得分:4)

这可以代表解决方案的起点。 在你继续阅读之前,我要回答的主要问题是:

  • 所有香草javascript
  • ajax调用加载新内容
  • 更改地址栏上的网址而不重新加载网页
  • 在浏览器历史记录中注册网址更改
  • seo friendly

但请注意,所有内容都以草稿代码的形式呈现,以解释解决方案,如果您想在生产环境中实现代码,则需要改进代码。

让我们从索引页面开始。

的index.php

<!DOCTYPE html>
<html>
<head>
    <title>Sample page</title>
    <meta charset="UTF-8">
    <script type="text/javascript" src="ajax_loader.js"></script>
</head>
<body>

<h1>Some static content</h1>
<a href="?main_content=external_content.php">
    Link to load dynamic content
</a>
<div id="main_content">
    <!--
        Here is where your dynamic content will be loaded.

        You can have as many dynamic container as you like.

        In my basic example you can attach one link to a
        single container but you can implement a more
        complete solution to handle multiple containers
        at the same time
    -->

    <!-- Leave this empty for the moment... some php will follow -->
</div>
</body>
</html>

现在让我们看看javascript如何处理用ajax加载内容的链接

ajax_loader.js

window.onload = function() {

        var load = function(e) {
            // prevent browser to load link
            event.preventDefault();

            // exit if target is undefined
            if(typeof(e.target) == 'undefined' ) {return;}

            // exit if clicked element is not a link
            if (e.target.tagName !== 'A') {return;}

            // get href from clicked element
            var href = e.target.getAttribute("href");

            // retrieve container and source
            var href_parts = href.split('=');
            var container = href_parts[0].substr(1);
            var source = href_parts[1];

            // instantiate a new request
            var request = new XMLHttpRequest();

            // bind a function to handle request status
            request.onreadystatechange = function() {
                if(request.readyState < 4) {
                    // handle preload
                    return;
                }
                if(request.status !== 200) {
                    // handle error
                    return;
                }
                if(request.readyState === 4) {
                    // handle successful request
                    successCallback();
                }
            };

            // open the request to the specified source
            request.open('GET', source, true);
            // execute the request
            request.send('');

            successCallback = function() {
                // on success place response content in the specified container
                document.getElementById(container).innerHTML = request.responseText;

                // change url in the address bar and save it in the history
                history.pushState('','',"?"+container+"="+source);
            }
        };

        // add an event listener to the entire document.
        document.addEventListener('click', load, false);
        // the reason why the event listener is attached
        // to the whole document and not only to the <a>
        // elements in the page is that otherwise the links
        // included in the dynamic content would not
        // liste to the click event

    };

现在让我们回顾一下html的一些具体元素

如前所述,建议的脚本会将行为附加到任何链接,您只需要格式化它,以便load()函数正确读取。格式为“?container_name = filename.php”。其中container_name是要在其中加载内容的div的id,而filename.php是ajax要检索内容的文件的名称。

因此,如果你的'external_content.php'文件中有一些内容并希望它在id为'main_content'的div中加载,那么你就是这样做

<a href="?main_content=external_content.php">Your link</a>
<div id="main_content"></div>

在此示例中,当页面首次加载时,div“main_content”为空,并且会在单击带有external_content.php文件内容的链接时填充。 同时,浏览器的地址栏将从中更改 http://www.example.com/index.phphttp://www.example.com/index.php?main_content=external_content.php 这个新网址将在您的浏览器历史记录中注册

现在让我们进一步了解我们如何才能使这个SEO友好 http://www.example.com/index.php?main_content=external_content.php 是一个真实的地址,加载页面时'main_content'div不为空。

我们可以添加一些PHP代码来处理这个问题。 (请注意,你甚至可以写一些javascript到类似的工作,但既然你提到使用服务器端语言我决定去php)

<a href="?main_content=external_content.php">Load</a>
<div id="main_content">
    <?php dynamicLoad('main_content','default_main_content.php'); ?>
</div>

在展示它之前,我想解释php函数dynamicLoad()的作用。它需要两个参数,第一个相当于容器id,第二个是默认内容所在的文件。 更清楚的是,如果请求的网址是 http://www.example.com/ 该函数将default_main_content.php的内容放在main_content div中 但是如果浏览器请求的网址是 http://www.example.com/index.php?main_content=external_content.php 然后函数会将external_content.php的内容放在main_content div中。

此机制有助于页面对SEO友好且用户友好,因此当搜索引擎爬虫将遵循href时 “?main_content = external_content.php” 这会带来网址 “http://www.example.com/index.php?main_content=external_content.php”将找到与ajax调用动态显示的相同内容。 对于将通过刷新或历史记录重新加载页面的用户也是如此。

这是简单的dynamicLoad()php函数

<?php
    function dynamicLoad($contaner,$defaultSource){
        $loadSource = $defaultSource;
        if(isset($_GET[$contaner])) {
            $loadSource = $_GET[$contaner];
        }
        include($loadSource);
    }
?>

如前所述,这不是准备生产的代码,它只是对您提出的请求的可能解决方案的解释

  

更改显示的网址并根据该更改的内容   页面并使网页的网址和内容成为机器人   友好

答案 1 :(得分:3)

如果你真的关心你的搜索引擎优化你不应该使用AJAX动态填充你的网站,这不是关于谷歌蜘蛛,因为它可以以简单的方式阅读JavaScript,但对于其他搜索引擎蜘蛛。

最好和最古老的方法是使用普通路线,但您可以使用nodeJS进行模拟并做出反应,这样您就可以使用Javascript填充您的内容,如果我有正确的话,这称为Isomorphic。

http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/

更新

  

只能在客户端运行的应用程序无法向抓取工具提供HTML,因此默认情况下搜索引擎优化效果不佳。 Web爬虫通过向Web服务器发出请求并解释结果来起作用;但是如果服务器返回一个空白页面,那就没什么价值了。有一些解决方法,但不是没有跳过一些箍。   来源Airbnb网站

不同之处在于用户使客户端呈现的速度过期,网络抓取工具从服务器获取内容。

答案 2 :(得分:3)

实际上有一种方法可以做到这一点。我使用AngularJS,正如有人正确地指出谷歌将为您的网站编制索引,现在没有问题(如果我没记错的话,去年6月)。 Facebook和其他此类网站不会抓取JavaScript,因此为了做到这一点,您需要另一种解决方案。

最简单的方法是使用prerender.io,因为它将使用_escaped_fragment_参数并生成页面的HTML快照。只有在请求页面时才会生成这些内容。

除此之外,唯一的另一个真正的解决方案是使用PhantomJS并自己创建快照。这并不像听起来那么困难。您可以使用Gulp或Grunt之类的东西在更改视图时生成快照。

我希望有所帮助。

答案 3 :(得分:2)

您可以使用React等工具进行服务器端渲染,并在应用程序(js)中使用history.pushState()更改URL。
第一个问题(更改URL)请查看this example
对于您的第二个问题(编写代码一次),使用服务器端渲染方法将解决问题因为它将所需的元素呈现为HTML字符串,然后将其作为响应发送给客户端。

答案 4 :(得分:0)

我认为您的网页未正确编入索引的主要问题可能是因为网址中的#

对于使用AngularJS的SEO,请查看以下链接