草庐IT

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

coder 2024-04-23 原文

我想知道是否可以更改显示的 url 并据此更改页面内容,并使 url 和页面内容对机器人友好(这意味着机器人实际上可以为它们编制索引)。

我已经尝试过使用 AJAX 动态加载数据并使用 angularjs 路由,但它们都不能被机器人索引。

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

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

更新

适用于所有语言且不依赖的无库解决方案/结构将是最准确的答案!

最佳答案

这里有一些东西可以代表解决方案的起点。 在继续阅读之前,请记住以下关于我的回答的主要事项:

  • 所有原生 javascript
  • ajax 调用加载新内容
  • 在不重新加载页面的情况下更改地址栏上的 url
  • 在浏览器历史记录中注册 url 更改
  • 搜索引擎优化友好

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

让我们从索引页开始。

索引.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 并且这个新的 url 将在您的浏览器历史记录中注册

现在让我们更进一步,看看我们如何使这个 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,第二个相当于默认内容所在的文件。 更清楚地说,如果请求的 url 是 http://www.example.com/ 该函数会将 default_main_content.php 的内容放入 main_content div 但是如果浏览器请求的 url 是 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);
    }
?>

正如第一行所说,这不是准备用于生产的代码,它只是对您提出的请求的可能解决方案的解释

to change the url showing and according to that change the content of the page and make the urls and the content of the page to be robot friendly

关于javascript - 如何在不刷新页面的情况下更改路由和内容? (机器人友好),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37511989/

有关javascript - 如何在不刷新页面的情况下更改路由和内容? (机器人友好)的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  7. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  8. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  9. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  10. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

随机推荐