【问题标题】:How to explain to the browser to remember the Ajax request?如何向浏览器解释要记住 Ajax 请求?
【发布时间】:2016-04-14 02:45:00
【问题描述】:

浏览器和我的应用程序的“返回”按钮有问题。 webapp 使用 ajax 和标准请求。这一切都是这样发生的:

  1. 我向list.jsp 页面发出 GET 请求 - 如果您检查我在下面提供的临时链接,这是您在应用程序中看到的第一页。现在我们在第 1 页(整个页面已重新加载)

  2. 我向页面 4 发出 Ajax 请求(单击链接 - 即页码)。只有页面的一部分被重新加载 - 一切正常。因此,现在我们在第 4 页

  3. 我向页面 5 发出 Ajax 请求(单击链接 - 即页码)。只有页面的一部分被重新加载 - 一切正常。因此,现在我们在第 5 页

  4. 现在我按下浏览器的“返回”按钮(回到历史记录一步) - 什么都没有发生。浏览器控制台未显示任何更改。

  5. 这一步我再次按下浏览器的“返回”按钮。事实证明,这一步执行正确。 GET 请求发生了。

发生了什么事?为什么浏览器不记得第 3 步发生的更改?如何指示浏览器对 ajax 请求所做的更改进行step back to history

您可以通过temp link在线查看。试着浏览这些页面。粉色方块是当前页面指示符。


更新 1:

此代码在加载程序完成加载资源后初始化。

$(function() {

    $(window).on('hashchange', refreshByHash);

    refreshByHash();

    function refreshByHash() {              
        var hash = window.location.hash; 
        console.log("hash = " + hash.substring(1));

        /* $.ajax({

               url : 'paginator.action?page=' + hash, // action
               type : 'GET', //type of posting the data
                dataType : 'html',
                async: true,
                success : function(htmlData) {
                    $('#paginator').html(htmlData);
                },
                error : function(xhr, ajaxOptions, thrownError) {
                    alert('An error occurred! ' + thrownError);
                },

            }); */

       }

 });

【问题讨论】:

  • 你使用原始的 javascript 还是一些框架,比如 angularjs 或 jquery?
  • 另外一个内联 MCVE 会很棒,所以回答你问题的人不必从头开始建立一个例子
  • @hege_hegedus 我使用 jquery 和 javascript 进行分页更改。核心框架是java。
  • @hege_hegedus 很难让内联 MCVE 重现正在发生的事情

标签: jquery ajax web-applications


【解决方案1】:

当用户点击#idPage(顺便说一句,使用类,现在你有多个具有相同ID和that's not good的元素)时,因为href属性为空,浏览器将加载#(并且会去到页面顶部)。

您应该防止用户点击链接时的默认行为,例如

$('body').on('click', '#idPage', function(e) {
   // some code goes here
   e.preventDefault();
});

标签 (#) 对后退/前进按钮有影响。如果您附加主题标签并单击“返回”,浏览器会将您返回到应用主题标签之前的状态。

【讨论】:

  • If you append hashtag 是什么意思?如果现在 href 包含 # 那么如何更改它?喜欢#someValue 吗?我可以在 $('body').on('click', '#idPage', function(e) { 后面加上 e.preventDefault(); 行吗?顺便说一下e参考element
  • 您应该在关闭}); 之前添加该行。不,e 表示事件。
  • 我已经按照你说的修改了脚本,现在浏览器back button在第一次点击back后不可用....你可以通过临时链接查看。我还在页面链接中将div 更改为class
  • 还有一个错误:Uncaught ReferenceError: e is not defined(anonymous function) @ pagin_scripts.js:21x.event.dispatch @ jquery-1.10.2.min.js:5v.handle @ jquery-1.10.2.min.js:5
  • 链接不可用。
【解决方案2】:

我建议您在 url 中放置一个 hash 参数,这样浏览器将正确处理历史记录并监听 hashchange 事件。在大多数情况下,您可以将页面状态直接存储在那里,因此您不必实现自己的历史处理。我整理了一些 MCVE:

$(function() {

  // setup some pagination bar
  for (var i = 1; i < 11; i++) {
    $('#pages').append(
        $('<a/>').text(i).attr('href','#'+i)
    );
    $('#pages').append($('<span/>').text('.'));
  }

  // load contents of page i
  function _uiPage(i) {
      // imitate some XHR
      setTimeout(function() {
          $('#page-content').text('This is page ' + i);
      }, 200);
  }
  
  // load contents of current page based on hash
  function refreshByHash() {
      var hash = window.location.hash;
      _uiPage(hash ? +hash.substring(1) : 1);
  }
  
  // refresh on hash change
  $(window).on('hashchange', refreshByHash);
  // initial state on page load
  refreshByHash();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="pages"></div>
<div id="page-content"></div>

注意:Chrome 的后退按钮会在活动的 iframe 中返回,所以点击部分页面后,可以按后退按钮来测试行为,外框、StackOverflow 本身不会改变。

也看看问题:How to manage browser “back” and “forward” buttons when creating a javascript widget


编辑1

$(function() {
  $(window).on('hashchange', refreshByHash);
  refreshByHash();

  function refreshByHash() {              
    var hash = window.location.hash; 
    // ----- strip the hashmark here -----
    hash = hash ? hash.substring(1) : '';
    console.log("hash = " + hash);

    $.ajax({
      url : 'paginator.action?page=' + hash, // action
      type : 'GET', //type of posting the data
      dataType : 'html',
      async: true,
      success : function(htmlData) {
        $('#paginator').html(htmlData);
      },
      error : function(xhr, ajaxOptions, thrownError) {
        alert('An error occurred! ' + thrownError);
      },
    });
  }
});

【讨论】:

  • 我尝试将您的解决方案实施到我的代码中,但遇到了两个问题。请参阅更新 1 代码脚本。 --------------------------------------- 1) 无法从注释的位置获取 ajax 请求。如何将hash value 传递给ajax 代码?---------------------------- 2)必须仅执行该ajax 请求并且仅当按下浏览器按钮,但每次按下链接或按下浏览器按钮时,所有代码都会运行。
  • @rozero 我真的不明白在没有 ajax 请求的情况下按下页码后如何显示页面。如果您可以在第一次显示它们,那么下次按下浏览器按钮时,您也可以在不使用 ajax 的情况下显示它们。
  • 我在pagin_scripts.js 中有另一个脚本,您可以尝试检查temp link。该脚本由脚本加载器加载。从该代码中,我通过按页码管理要由 ajax 更新的内容。但是更新 1part 中的代码用于管理例如后退按钮。我是这么理解的。
  • @rozero 您在其中有三个功能基本相同。我仍然不明白为什么第一次加载会与其他加载不同。
猜你喜欢
  • 1970-01-01
  • 2011-02-04
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 2011-10-28
  • 2010-09-17
相关资源
最近更新 更多