【问题标题】:How to show Ajax requests in URL?如何在 URL 中显示 Ajax 请求?
【发布时间】:2011-03-13 11:08:18
【问题描述】:

我想要的是拥有改变页面一部分的链接,以及它的动态 URL,我可以在其中指定变量,例如 #calendar=10_2010tabview=tab2

Check this for an exact example: CLICK HERE FOR EXACT DEMO

所以这是我需要的链接格式:

#calendar=10_2010&tabview=tab2

我需要在链接中包含变量,例如 calendar 和 tabview,这样我就可以在一个页面上更改多个内容而无需重新加载。


或者像http://www.wbhomes.com.au这样的另一种格式,这正是我想要的正是,但是第一种格式也很好,但它更漂亮。

  • http://wbhomes.com.au/#/propertiesforsale/houseandland/quinnsbeach-waterland1

要求

  • 需要从任何地方访问 例如一封邮件,或者如果我只是 写在网址栏中。

  • 链接应该在历史记录中,所以如果我按下后退或前进按钮,则需要访问页面。

  • 页面刷新也需要工作。


一些资源:

例子:

一些教程:


请帮帮我!我从来没有找到任何解决方案来做到这一点,但我不想使用 jquery 或任何 API 或任何库,我想要一个有效的 Javascript/AJAX 和 PHP 脚本。

【问题讨论】:

  • 我不太关注你。 AJAX 与您所描述的内容在哪里发挥作用? # 指的是页面上的锚点。我不认为那是你想要的。您可能需要一个查询字符串,然后处理此服务器端。您可以在客户端,在这种情况下,您将解析 URL 的查询字符串并在那里获取值。
  • @DA - 他在谈论 Facebook 所做的事情,将 AJAX 请求的路径放入哈希中。
  • 当我点击链接时,当内容发生变化时,ajax 会进入,该部分正在工作,但我不知道如何显示 URL 的变化:)
  • 正是@Matchu,facebook 就是一个很好的例子。

标签: php ajax url-rewriting fragment-identifier hashchange


【解决方案1】:

对于您问题中链接的演示,实现该功能实际上非常简单 - 因为它根本不使用任何 AJAX(当您开始将 AJAX 添加到组合中时,它变得更加困难 - 稍后解释)。要实现该功能,您将;升级您的链接以使用哈希,然后绑定到 hashchange 事件。不幸的是,hashchange 事件不是跨浏览器兼容的,虽然幸运的是有许多“历史/远程插件”可用 - 我们多年来首选的一个已被证明是 jQuery History,它是开源的,得到了很大的支持并正在积极开发:-)。

虽然,当谈到像 Facebook、WBHomes 和 Balupton.com 这样的网站添加 AJAX 功能时,您将开始面临一系列严重困难的问题! (我知道我是最后两个站点的首席架构师!)。其中一些问题是:

  • 如何优雅而轻松地升级某些内部链接以使用历史记录和 AJAX 功能,并检测哈希何时更改?同时保持其他链接像以前一样工作。
  • 如何从“www.yoursite.com/myapp/a/b/c”重定向到“www.yoursite.com/myapp/#/a/b/c”?并且仍然为用户保持流畅的体验,使 3 次必要的重定向尽可能流畅。
  • 如何使用 AJAX 提交表单值和数据并更新哈希?如果他们不支持 Javascript,反之亦然。
  • 如何检测 AJAX 请求需要页面的哪个特定区域?这样子页面就会显示正确的页面。
  • AJAX状态改变时如何改变页面标题?和其他非页面内容。
  • 如何在 AJAX 状态加载和更改时执行漂亮的前奏/后奏效果?这样用户就不会被蒙在鼓里。
  • 通过AJAX登录时如何更新侧边栏登录信息?显然,我们不希望左上角的登录按钮再出现。
  • 对于没有启用JS的用户,如何仍然支持网站?这样它可以优雅地降级并且仍然可以被搜索引擎索引。

我所知道的唯一一个试图解决提到的所有这些极其困难的问题的开源且可靠的项目已被证明是 jQuery Ajaxy。它实际上是对前面提到的 jQuery History 项目的扩展,提供了一个漂亮优雅的高级界面来添加 AJAX 功能来解决幕后的那些难题,因此我们不必担心它们。这也是前面提到的最后几个商业网站使用的选择解决方案。

祝你好运,如果您还有其他问题,请在此答案上发表评论,我会尽快处理 :-)

更新:现在有 HTML5 History API(pushState、popState),它弃用了 HTML4 hashchange 功能。 History.js 现在是 jQuery History 的继承者,并为 HTML5 History API 提供跨浏览器兼容性,并为 HTML4 浏览器提供 optional hashchange 后备。 jQuery Ajaxy 将为 History.js 升级

【讨论】:

  • 嘿!非常感谢您的回答,我知道我的演示不是用 AJAX 制作的,但是我将使用 AJAX 制作我自己的,但该演示演示了我想要达到的效果,您的示例:http://wbhomes.com.au/#/home 非常酷,这是 100% 我想要的,没有? 之类的东西,但对我来说任何版本都很好,但如果你能告诉我你是如何做到的,我会非常非常高兴:)。而且我知道这非常困难,因为没有人发布(我没有找到)任何关于它的内容,而且我真的不知道如何制作它,我不是 javascript 专业人士。
  • 谢谢伙计,我很高兴能帮上忙。是的,我完全同意 wbhomes 网站非常酷!我已经修改了我的帖子以进入用于它的解决方案(jQuery Ajaxy),这样应该可以清除任何未说明的内容:-) 如果您想了解更多信息,请务必随时发表评论,或者您可以随时发表评论直接在我的网站 www.balupton.com 上与我联系
  • 嗨@balupton! Ajaxy 很好很酷,但我认为它存在很大的问题。我无法指定要将content 放在哪里。例如,我有link1 - onclick calls page1.php 和link2 - onclick calls page2.php,但我希望link1 更改div content1 和link2 更改div content2,我希望你明白我在说什么:) 我认为这个功能几乎是完美的;)
  • 还有别的,比如我有一个search我写在里面balupton然后提交,然后ajaxy改变了内容但是URL没有改变。
  • 还有别的东西,如果你也能用纯 Javascript 制作它,那就太棒了!我认为如果你能做到这些,Ajaxy 将成为想要构建基于 Ajax 的应用程序的开发人员最有用和最强大的工具之一 :)
【解决方案2】:

我认为您可以使用 HTML5 中的 onHashChange 事件或使用在不完全支持 HTML 5 的浏览器中模拟“散列”行为的 JavaScript 库来非常轻松地做到这一点。 MooTools onhashchange 可能是这样的一个库,但还有很多其他的。

如果你有一个支持 HTML 5 的浏览器,或者类似行为的库,只需使用:

window.setash("#newsection");
从 javascript 更改为新内容,和/或回调该 onHashChange 事件以拦截它,具体取决于您的用例场景。

【讨论】:

  • 确实,使用 onhashchage 是大多数人的做法 - 包括 gmail。
  • 问题是很多浏览器本身不支持onhashchage,或者他们有怪癖。提供的库添加了对旧版浏览器的支持,而且这只是为了挂钩哈希,而不是 AJAX 范式的工作原理。
【解决方案3】:

CorMVC Jquery Framework 就是这样完成的,它是开源的,你可以挖掘源代码并从中获取逻辑。

实际上它非常简单。创作者在下面的视频中很好地讲述了这一点。

http://www.bennadel.com/resources/jing/2009-12-21_0933.swf

PS 抱歉不能发布第二个链接,因为我是新用户。

【讨论】:

    【解决方案4】:

    Szevasz.. :)

    HTML

    <a href="/bye.php?user=abc&page=messages" 
       onclick="return goToWithAjax(this);">bye</a> 
    

    Javascript

    function goToWithAjax(hash) {
      hash = hash.href ? hash.getAttribute("href", 2) : hash;
      ajax( hash, function( response ) {
        document.getElementById("content").innerHTML = response;
      });
      hash = ("#!/" + hash).replace("//","/");
      window.location.hash = hash;
      return false;
    }
    
    //////////////////////////////////////////////////////////////////////////////
    
    function getXmlHttpObject() {
        var xmlHttp;
        try {
            xmlHttp = new XMLHttpRequest();
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
        return xmlHttp;
    }
    
    function ajax(url, onSuccess, onError) {
        var xmlHttp = getXmlHttpObject();
        xmlHttp.onreadystatechange = function () {
            if (this.readyState == 4) {
                // onError
                if (this.status != 200) {
                    if (typeof onError == 'function') {
                        onError(this.responseText);
                    }
                }
                // onSuccess
                else if (typeof onSuccess == 'function') {
                    onSuccess(this.responseText);
                }
            }
        };
        xmlHttp.open("GET", url, true);
        xmlHttp.send(null);
        return xmlHttp;
    }​
    

    【讨论】:

    • 嘿@galambalazs,谢谢你的脚本,我会测试它!泽瓦兹:D
    • 如果我在#hello 之前有一些东西怎么办?示例:example.com/?ice=cream#best
    • 查看我的更新,现在您有了一个非常通用的解决方案。 :) 您可以使用文件名或带有哈希的 url。也可以指定文件扩展名,默认为php。
    • URL 没有改变。 :S 这是我的使用方法:&lt;a href="http://192.168.2.104/?user=&lt;?php echo $user-&gt;username?&gt;#messages" onclick="return goToWithAjax('http://192.168.2.104/pages/messages.php');"&gt;messages&lt;/a&gt;
    • 进入你做 ajax 的每个网站。这将帮助您恢复 ajax 的东西。就像用户来自链接一样。
    【解决方案5】:

    这是大多数新的 AJAXian 开发人员无法理解的。这是一个很容易解决的问题。

    您首先需要的是 jQuery 核心,它在 jquery.com 上免费

    接下来,您将需要 Ben Alman 的 jQuery hash change even 插件,您可以在这里找到:http://benalman.com/projects/jquery-hashchange-plugin/ 对于支持 html5 hashchange 事件的较新版本的浏览器,您将不需要它,但对于旧版本的浏览器则需要.您无需执行任何操作,只需将此脚本包含在您的页面中,其余部分由它处理。

    现在对于您的链接,您需要像这样以查询字符串的方式构造它们:

    <a href="user.php?q=/topic/article" class="dynlnk">Link Text/Image</a>
    

    现在您有了指向页面的链接,并且可以在 php 中处理,以防 javascript 被关闭。您所要做的就是使用超级全局 $_GET 并解析查询字符串来处理页面内容。

    现在您需要在页面上的 javascript 中使您的链接触发 hashchange。您可以通过将 ?q= 替换为 # 来做到这一点。

    $(".dynlnk").each(function(){
        $(this).attr("href", $(this).attr("href").replace("?q=", "#"));
    });
    

    现在您的链接将触发 hashchange,唯一剩下要做的就是将 hashchange 绑定到执行某些操作的函数。这可以使用 jQuery 非常简单地完成,如下所示:

    $(window).bind( 'hashchange', function(e){
    
        //this splits the part after the hash so you can handle the parts individually.
        //to handle them as one just use location.hash
        pageparts = location.hash.split("/");
    
    });
    

    现在只需添加您所做的任何代码来处理您的 ajax 和内容。

    现在您只需要最后一点 javascript 来触发 hashchange,以防页面加载时使用哈希开始,因此您只需在页面加载时调用 windows 触发函数

    $(window).trigger( 'hashchange' );
    

    希望这足够清楚,如果没有,请随时与我联系以提出更多问题。

    【讨论】:

      【解决方案6】:

      使用哈希链接允许可收藏/可共享的链接触发 JavaScript 代码,而不是重新加载页面。 Ben Almans jQuery hashchange event 允许您将事件处理程序绑定到 hashchange 事件,此插件适用于通常不支持此功能的旧浏览器。绑定到 hashchange 的事件处理程序可以读取 url 的哈希部分,并调用任何函数。

      // register event handler
      function bindHashchange() {
      
          $(window).bind('hashchange', function(event) {
              event.preventDefault();
              var label = location.hash.substring(1);
              handleLabel(label);
          });
      
          // trigger event so handler will be run when page is opened first time
          // otherwise handler will only run when clicking on hash links
          $(window).trigger('hashchange');
      }
      
      // read and handle hash part of url
      function handleLabel(label) {
      
          if ( label.length > 0 ) {
              // using label from url
              switchPage(label);
          } else {
              // use the default label, if no hash link was present
              switchPage('start');
          }
      }
      
      // in this case, load hidden <div>'s into a <div id="content">
      function switchPage(label) {
          if ( label == 'start ) {
              $('div#content').html($('div#start'));
          } else if ( label == 'some_other_page' ) {
              // do something else
          }
      }
      

      此其他事件处理程序可以处理同一 url 中由点 ('.') 分隔的 2 个参数。

      function processHash() {
      
          var str = location.hash.substring(1);
          var pos = $.inArray('.', str);
      
          var label = '';
          var arg = '';
      
          if ( pos > -1 ) {
              label = str.substring(0, pos);
          } else {
              label = str.substring(0);
          }
      
          if ( pos > 1 ) {
              arg = str.substring(pos+1);
          }
      
          if ( label.length == 0 ) {
              // the default page to open of label is empty
              loadContent('start');
          } else {
              // load page, and pass an argument
              loadContent(label, arg);
          }
      }
      

      如果使用正则表达式,可以解析任意字符组合。

      var registry = {};
      
      // split on character '.'
      var args = label.split(/\./g);
      
      for ( i in args ) {
          var arg = args[i];
      
          // split on character '='
          var temp = arg.split('=');
          var name = temp[0];
          var value = temp[1];
      
          // store argument in registry
          registry[name] = value;
      }
      // registry is loaded, ready to run application that depends on arguments
      

      这将转换网址:

      mysite/#company.page=items.color=red

      进入以下 JavaScript 对象:

      对象 { company=undefined, page="items", color="red"}

      那么只需要在你选择的元素上运行 jQuery 的 show() 或 hide() 函数即可。

      这可以转换为非 jQuery JavaScript,但是您将失去 Ben Alman 提供的功能,这对于可移植的解决方案至关重要。

      【讨论】:

        【解决方案7】:

        您想要的是一种在AJAX 中支持history 的方法,这可以使用许多现有的库来完成。我建议阅读YUI 3 page on history。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-04
          • 2011-08-28
          • 1970-01-01
          • 1970-01-01
          • 2015-03-27
          • 1970-01-01
          相关资源
          最近更新 更多