【问题标题】:Reload browser window after POST without prompting user to resend POST dataPOST 后重新加载浏览器窗口而不提示用户重新发送 POST 数据
【发布时间】:2011-06-19 16:13:05
【问题描述】:

当用户访问我的网站时,每个页面上都有一个“登录”链接。单击它会使用一些 JavaScript 来显示一个覆盖窗口,提示用户输入他们的凭据。输入这些凭据后,将对 Web 服务器进行 Ajax 调用以验证它们;如果它们是有效的,则会发回一个身份验证票证 cookie 并重新加载页面,以便显示页面上特定于经过身份验证的用户或(现在)当前登录用户的任何内容。

我正在通过脚本完成页面重新加载:

window.location.reload();

这对于通过 GET 请求(绝大多数)加载的页面非常有效,但有些页面使用回发表单。因此,如果用户转到这些页面之一,执行回发,然后选择登录,当window.location.reload() 脚本运行时,他们会收到一个对话框,询问他们是否要重新提交 POST 正文。

我想解决这个问题,我可以告诉浏览器重新加载页面,所以我尝试了:

window.location.href = window.location.href;

但是浏览器并没有对上述语句采取任何行动,我想是因为它认为新 URL 与旧 URL 相同。如果我将以上内容更改为:

window.location.href = window.location.pathname;

它重新加载页面,但我丢失了任何查询字符串参数。

我当前的解决方法已经足够了,但并不漂亮 - 简而言之,我将查询字符串参数附加到当前的 window.location.href 值,然后通过调用 reloadPage("justLoggedIn") 将其分配回 window.location.href,其中 reloadPage 函数是:

function reloadPage(querystringTackon) {
    var currentUrl = window.location.href;

    if (querystringTackon != null && querystringTackon.length > 0 && currentUrl.indexOf(querystringTackon) < 0) {
        if (currentUrl.indexOf("?") < 0)
            currentUrl += "?" + querystringTackon;
        else
            currentUrl += "&" + querystringTackon;
    }

    window.location.href = currentUrl;
}

这可行,但它导致 URL 为 www.example.com/SomeFolder/SomePage.aspx?justLoggedIn,这看起来很俗气。

在 JavaScript 中有没有办法让它重新加载 GET 而不提示用户重新提交 POST 数据?我需要确保任何现有的查询字符串参数都不会丢失。

【问题讨论】:

  • 怎么样:window.location.href = window.location.href + '&amp;reload=1'; ?
  • @jnpcl:本质上,这是我当前的解决方法(请参阅上面提到的reloadPage 函数),但感觉很俗气。我希望有一个更优雅的解决方案。
  • 奇怪的是 window.location.href = window.location.href 在 Firefox 和 Chromium 下为我工作(重新加载页面)。也许尝试window.location.replace(window.location.href)(这另外使页面重新加载对用户历史记录透明)...

标签: javascript


【解决方案1】:
window.location.href = window.location.href;

不要问我为什么它有效..但它确实有效:)。
就像js引擎解释我想的逻辑一样。

【讨论】:

  • 对 GET 也不起作用,至少在 Firefox 上这不起作用。
  • 有趣的是,这显然没有做它应该做的事情,但是访问这个页面的人继续投票......也许人们来到这个页面试图做 相反 i> OP 的意图是什么? (例如“重新加载”页面并省略 POST 参数)
  • 感谢您的回答。它确实可以跨浏览器工作。但是我必须声明它只适用于所有浏览器,如果在提交表单后它不加载相同的页面。 @rinogo
  • 这不是一个好的答案,因为只是没有发送帖子数据。
【解决方案2】:

您可能需要做的是在 POST / Form Handler 脚本运行后重定向用户。

在 PHP 中是这样完成的...

<?php
// ... Handle $_POST data, maybe insert it into a database.
// Ok, $_POST data has been handled, redirect the user
header('Location:success.php');
die();
?>

...这应该允许您刷新页面而不会收到“再次发送数据”警告。

您甚至可以重定向到同一页面(如果这是您要发布的内容),因为 POST 变量不会在标题中发送(因此不会在刷新时重新发布)

【讨论】:

  • 问题是应用程序是一个 ASP.NET Web 窗体应用程序,所以有很多回发,我无法修改这个根深蒂固的 ASP.NET 功能。
  • 对 .NET 功能的修改可能需要另一个问题。我想我想说的是,这个问题的“解决方案”将是攻击原因(这不会在发布后重定向用户)——我希望我能更多地了解 .NET 来帮助你=/
【解决方案3】:

这也有效:

window.location.href = window.location.pathname + window.location.search

【讨论】:

  • 也许可以,但这有效,并且比先前建议“window.location.href = window.location.href;”的答案更好会起作用,而它不起作用。
  • 这不会发送帖子值
【解决方案4】:

这对我有用。

window.location = window.location.pathname;

经过测试

  • Chrome 44.0.2403
  • IE 边缘
  • 火狐39.0

【讨论】:

    【解决方案5】:

    使用

    RefreshForm.submit(); 
    

    而不是

    document.location.reload(true); 
    

    【讨论】:

    • 如果你使用 jQuery,你可以给你的提交按钮添加一个唯一的 id 然后调用$("my_button_id").click()
    【解决方案6】:

    这也可以通过 POST/REDIRECT/GET 模式解决。
    哪个更优雅:
    How do I reload a page without a POSTDATA warning in Javascript?

    【讨论】:

      【解决方案7】:

      我和你有同样的问题。

      这就是我所做的(动态生成的 GET 表单,操作设置为 location.href,隐藏输入的新​​值),它似乎适用于所有浏览器:

      var elForm=document.createElement("form");
      elForm.setAttribute("method", "get");
      elForm.setAttribute("action", window.location.href);
      
      var elInputHidden=document.createElement("input");
      elInputHidden.setAttribute("type", "hidden");
      elInputHidden.setAttribute("name", "r");
      elInputHidden.setAttribute("value", new Date().getTime());
      elForm.appendChild(elInputHidden);
      
      if(window.location.href.indexOf("?")>=0)
      {
          var _arrNameValue;
          var strRequestVars=window.location.href.substr(window.location.href.indexOf("?")+1);
          var _arrRequestVariablePairs=strRequestVars.split("&");
          for(var i=0; i<_arrRequestVariablePairs.length; i++)
          {
              _arrNameValue=_arrRequestVariablePairs[i].split("=");
      
              elInputHidden=document.createElement("input");
              elInputHidden.setAttribute("type", "hidden");
              elInputHidden.setAttribute("name", decodeURIComponent(_arrNameValue.shift()));
              elInputHidden.setAttribute("value", decodeURIComponent(_arrNameValue.join("=")));
              elForm.appendChild(elInputHidden);
          }
      }
      
      document.body.appendChild(elForm);
      elForm.submit();
      

      【讨论】:

      • 知道如何做这样的事情,但仍然允许保留 URL 上的哈希值吗?
      • @jamauss 您是否尝试过使用上面的代码在操作 URL 上设置哈希?
      • @jamauss 真正的问题是:你为什么不呢?
      • 我认为表单操作 URL 上不允许使用哈希。我现在试过了,我遇到的问题是它最终是 URL 编码的。因此,不是向 mysite/thread?thread=3#17 提交表单,而是向 mysite/thread?thread=3%2317 提交表单,因此线程查询字符串值最终为 3%2317 而不是 3。
      • 也许您可以通过设置查询参数“_fragment”来解决它,然后通过设置 location.href 进行第二次重新加载。
      【解决方案8】:

      这是一篇较旧的帖子,但我确实有更好的解决方案。创建一个包含所有帖子值作为隐藏字段的表单,并为表单命名,例如:

      <form name="RefreshForm" method="post" action="http://yoursite/yourscript">
          <input type="hidden" name="postVariable" value="PostData">
      </form>
      

      那么你需要在setTimeout 中做的就是RefreshForm.submit();

      干杯!

      【讨论】:

      • 这将尝试重新发送所有帖子信息。为什么要复制帖子数据并重新发送?你真正想做的是在没有帖子的情况下重新加载页面
      【解决方案9】:

      您可以尝试创建一个空表单,method=get,然后提交。

      <form id='reloader' method='get' action="enter url here"> </form>
      <script>
      // to reload the page, try
      document.getElementById('reloader').submit();
      </script>
      

      【讨论】:

        【解决方案10】:

        如果您的 URL 中有哈希“#”,则此处的所有解决方案都不起作用。这是唯一对我有用的解决方案。

        var hrefa = window.location.href.split("#")[1];
        var hrefb = window.location.href.split("#")[2];
        window.location.href  = window.location.pathname +  window.location.search + '&x=x#' + hrefa + '#' + hrefb;
        

        如果您有哈希,则 URL 必须不同才能重新加载。 &x=x 在这里做到这一点。只需将其替换为您可以忽略的内容即可。这是一个黑客,无法找到更好的解决方案..

        在 Firefox 中测试。

        【讨论】:

          【解决方案11】:

          当我们想在没有任何提示的情况下从子页面刷新父页面时。

          代码如下:

          window.opener.location.href = window.opener.location;

          这只是在没有任何提示的情况下刷新父页面。

          【讨论】:

            【解决方案12】:

            要使用所有参数重新加载打开器窗口(并非所有参数都使用 window.location.href 方法和使用 form.submit() 方法发送可能是晚一步)我更喜欢使用 window.history 方法。

            window.opener.history.go(0);
            

            【讨论】:

            • 注意:如果页面是在新窗口中打开的,这将重新加载前一个窗口,而不是您当前所在的窗口。至少在 Chrome 中。
            【解决方案13】:

            您可以通过指定无卸载处理程序来利用HTML prompt to unload 机制:

            window.onbeforeunload = null;
            window.location.replace(URL);
            

            WindowEventHandlers.onbeforeunload 中的See the notes section 了解更多信息。

            【讨论】:

              【解决方案14】:

              成功了

              <button onclick="window.location.href=window.location.href; return false;">Continue</button>
              

              没有return false; 它不起作用的原因是按钮单击会触发表单提交。如果有明确的 return false ,它不会进行表单提交,而只会重新加载作为先前 POST 到该页面的结果的同一页面。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-06-06
                • 1970-01-01
                • 2018-01-21
                • 2018-05-26
                • 1970-01-01
                • 1970-01-01
                • 2011-12-21
                • 2014-01-05
                相关资源
                最近更新 更多