Javascript 如何防止“确认表单重新提交”对话框?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6833914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:22:23  来源:igfitidea点击:

How to prevent the "Confirm Form Resubmission" dialog?

phpjavascriptjquerycodeigniter

提问by Martin Rose

How do I clean information in a form after submit so that it does not show this error after a page refresh?

提交后如何清理表单中的信息,以便在页面刷新后不显示此错误?

See image (from chrome):

见图片(来自铬):

The dialog has the text:

该对话框具有以下文本:

The page that you're looking for used
information that you entered. Returning to that
page might cause any action you took to be
repeated. Do you want to continue?

您要查找的页面使用
了您输入的信息。返回该
页面可能会导致
重复您执行的任何操作。你要继续吗?

I want this dialog not to appear.

我不希望这个对话框出现。

回答by Mike

Edit:It's been a few years since I originally posted this answer, and even though I got a few upvotes, I'm not really happy with my previous answer, so I have redone it completely. I hope this helps.

编辑:自从我最初发布这个答案已经有几年了,尽管我得到了一些赞成,但我对之前的答案并不满意,所以我已经完全重做了。我希望这有帮助。



When to use GETand POST:

何时使用GETPOST

One way to get rid of this error message is to make your form use GETinstead of POST. Just keep in mind that this is not always an appropriate solution(read below).

摆脱此错误消息的一种方法是让您的表单使用GET而不是POST. 请记住,这并不总是合适的解决方案(请阅读下文)。

Always use POSTif you are performing an action that you don't want to be repeated, if sensitive information is being transferred or if your form contains either a file upload or the length of all data sent is longer than ~2000 characters.

如果您正在执行不想重复的操作,如果正在传输敏感信息,或者如果您的表单包含文件上传或发送的所有数据的长度超过~2000 个字符,请始终使用 POST

Examples of when to use POSTwould include:

何时使用的示例POST包括:

  • A login form
  • A contact form
  • A submit payment form
  • Something that adds, edits or deletes entries from a database
  • An image uploader (note, if using GETwith an <input type="file">field, only the filename will be sent to the server, which 99.73% of the time is not what you want.)
  • A form with many fields (which would create a long URL if using GET)
  • 一个登录表单
  • 联系表格
  • 提交付款表格
  • 从数据库中添加、编辑或删除条目的东西
  • 图像上传器(注意,如果GET<input type="file">字段一起使用,则只会将文件名发送到服务器,这在 99.73% 的情况下不是您想要的。)
  • 包含多个字段的表单(如果使用 GET,则会创建一个长 URL)

In any of these cases, you don't want people refreshing the page and re-sending the data. If you are sending sensitive information, using GET would not only be inappropriate, it would be a security issue (even if the form is sent by AJAX) since the sensitive item (e.g. user's password) is sent in the URL and will therefore show up in server access logs.

在任何这些情况下,您都不希望人们刷新页面并重新发送数据。如果您正在发送敏感信息,使用 GET 不仅不合适,而且会是一个安全问题(即使表单是由 AJAX 发送的),因为敏感项目(例如用户密码)是在 URL 中发送的,因此会显示出来在服务器访问日志中。

Use GETfor basically anything else. This means, when you don't mind if it is repeated, for anything that you could provide a direct link to, when no sensitive information is being transferred, when you are pretty sure your URL lengths are not going to get out of control and when your forms don't have any file uploads.

基本上可以将 GET用于其他任何事情。这意味着,当您不介意它是否重复时,对于您可以提供直接链接的任何内容,当没有传输敏感信息时,当您非常确定您的 URL 长度不会失控时,并且当您的表单没有任何文件上传时。

Examples would include:

示例包括:

  • Performing a search in a search engine
  • A navigation form for navigating around the website
  • Performing one-time actions using a nonce or single use password (such as an "unsubscribe" link in an email).
  • 在搜索引擎中执行搜索
  • 用于浏览网站的导航表单
  • 使用随机数或一次性密码(例如电子邮件中的“取消订阅”链接)执行一次性操作。

In these cases POST would be completely inappropriate. Imagine if search engines used POST for their searches. You would receive this message every time you refreshed the page and you wouldn't be able to just copy and paste the results URL to people, they would have to manually fill out the form themselves.

在这些情况下,POST 是完全不合适的。想象一下,如果搜索引擎使用 POST 进行搜索。每次刷新页面时,您都会收到此消息,并且您无法将结果 URL 复制并粘贴给人们,他们必须自己手动填写表单。

If you use POST:

如果您使用POST

To me, in most cases even having the "Confirm form resubmission" dialog pop up shows that there is a design flaw. By the very nature of POSTbeing used to perform destructive actions, web designers should prevent users from ever performing them more than once by accidentally (or intentionally) refreshing the page. Many users do not even know what this dialog means and will therefore just click on "Continue". What if that was after a "submit payment" request? Does the payment get sent again?

对我来说,在大多数情况下,即使弹出“确认表单重新提交”对话框也表明存在设计缺陷。由于POST被用来执行破坏性操作的本质,网页设计师应该防止用户因意外(或故意)刷新页面而多次执行这些操作。许多用户甚至不知道此对话框的含义,因此只需单击“继续”即可。如果那是在“提交付款”请求之后呢?付款会再次发送吗?

So what do you do? Fortunately we have the Post/Redirect/Getdesign pattern. The user submits a POST request to the server, the server redirects the user's browser to another page and that page is then retrieved using GET.

所以你会怎么做?幸运的是,我们有Post/Redirect/Get设计模式。用户向服务器提交 POST 请求,服务器将用户的浏览器重定向到另一个页面,然后使用 GET 检索该页面。

Here is a simple example using PHP:

这是一个使用 PHP 的简单示例:

if(!empty($_POST['username'] && !empty($_POST['password'])) {
    $user = new User;
    $user->login($_POST['username'], $_POST['password']);

    if ($user->isLoggedIn()) {
        header("Location: /admin/welcome.php");
        exit;
    }
    else {
        header("Location: /login.php?invalid_login");
    }
}

Notice how in this example even when the password is incorrect, I am still redirecting back to the login form. To display an invalid login message to the user, just do something like:

注意在这个例子中,即使密码不正确,我仍然重定向回登录表单。要向用户显示无效的登录消息,只需执行以下操作:

if (isset($_GET['invalid_login'])) {
    echo "Your username and password combination is invalid";
}

回答by Tanmoy Datta

This method works for me well and I think the simplest way to do this is to use this javascript code inside the reloaded page's HTML.

这种方法对我很有效,我认为最简单的方法是在重新加载页面的 HTML 中使用这个 javascript 代码。

if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}

回答by zatatatata

It has nothing to do with your form or the values in it. It gets fired by the browser to prevent the user from repeating the same request with the cached data. If you really need to enable the refreshing of the result page, you should redirect the user, either via PHP (header('Location:result.php');) or other server-side language you're using. Meta tag solution should work also to disable the resending on refresh.

它与您的形式或其中的值无关。它被浏览器触发,以防止用户对缓存数据重复相同的请求。如果您确实需要启用结果页面的刷新,您应该通过 PHP ( header('Location:result.php');) 或您正在使用的其他服务器端语言重定向用户。元标记解决方案也应该可以禁用刷新时的重新发送。

回答by Garrett Smallwood

After processing the POST page, redirect the user to the same page.

处理 POST 页面后,将用户重定向到同一页面。

On http://test.com/test.php

http://test.com/test.php

header('Location: http://test.com/test.php');

This will get rid of the box, as refreshing the page will not resubmit the data.

这将摆脱该框,因为刷新页面不会重新提交数据。

回答by Kerwin Sneijders

You could try using AJAX calls with jQuery. Like how youtube adds your comment without refreshing. This would remove the problem with refreshing overal.

您可以尝试在 jQuery 中使用 AJAX 调用。就像 youtube 如何在不刷新的情况下添加您的评论。这将消除整体刷新的问题。

You'd need to send the info necessary trough the ajax call.
I'll use the youtube comment as example.

您需要通过 ajax 调用发送必要的信息。
我将使用 youtube 评论作为示例。

$.ajax({
    type: 'POST',
    url: 'ajax/comment-on-video.php',
    data: {
        comment: $('#idOfInputField').val();
     },
    success: function(obj) {
        if(obj === 'true') {
            //Some code that recreates the inserted comment on the page.
        }
    }
});

You can now create the file comment-on-video.phpand create something like this:

您现在可以创建文件comment-on-video.php并创建如下内容:

<?php
    session_start();

    if(isset($_POST['comment'])) {
        $comment = mysqli_real_escape_string($db, $_POST['comment']);
        //Given you are logged in and store the user id in the session.
        $user = $_SESSION['user_id'];

        $query = "INSERT INTO `comments` (`comment_text`, `user_id`) VALUES ($comment, $user);";
        $result = mysqli_query($db, $query);

        if($result) {
            echo true;
            exit();
        }
    }
    echo false;
    exit();
?>

回答by Felix Steiny

I had a situation where I could not use any of the above answers. My case involved working with search page where users would get "confirm form resubmission" if the clicked back after navigating to any of the search results. I wrote the following javascript which worked around the issue. It isn't a great fix as it is a bit blinky, and it doesn't work on IE8 or earlier. Still, though this might be useful or interesting for someone dealing with this issue.

我遇到过无法使用上述任何答案的情况。我的案例涉及使用搜索页面,如果在导航到任何搜索结果后点击返回,用户将获得“确认表单重新提交”。我编写了以下 javascript 来解决这个问题。这不是一个很好的修复,因为它有点闪烁,并且在 IE8 或更早版本上不起作用。尽管如此,尽管这对于处理此问题的人来说可能有用或有趣。

jQuery(document).ready(function () {

//feature test
if (!history)
    return;

var searchBox = jQuery("#searchfield");

    //This occurs when the user get here using the back button
if (history.state && history.state.searchTerm != null && history.state.searchTerm != "" && history.state.loaded != null && history.state.loaded == 0) {

    searchBox.val(history.state.searchTerm);

    //don't chain reloads
    history.replaceState({ searchTerm: history.state.searchTerm, page: history.state.page, loaded: 1 }, "", document.URL);

    //perform POST
    document.getElementById("myForm").submit();

    return;
}

    //This occurs the first time the user hits this page.
history.replaceState({ searchTerm: searchBox.val(), page: pageNumber, loaded: 0 }, "", document.URL);

});

回答by Doug Lerner

I was having this problem and added this JavaScript to the bottom of my page (read it at https://www.webtrickshome.com/faq/how-to-stop-form-resubmission-on-page-refresh) and it seemed to work. It seems much simpler a solution. Any drawbacks?

我遇到了这个问题并将这个 JavaScript 添加到我的页面底部(在https://www.webtrickshome.com/faq/how-to-stop-form-resubmission-on-page-refresh阅读它),它似乎上班。解决方案似乎要简单得多。有什么缺点吗?

<script>
if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}
</script>

Thanks,

谢谢,

doug

道格

回答by Eugen Konkov

It seems you are looking for the Post/Redirect/Getpattern.

看来您正在寻找Post/Redirect/Get模式。

As another solution you may stop to use redirecting at all.

作为另一种解决方案,您可以完全停止使用重定向。

You may process and render the processing result at once with no POSTconfirmation alert. You should just manipulate the browser history object:

您可以立即处理并呈现处理结果,无需POST确认提示。您应该只操作浏览器历史记录对象:

history.replaceState("", "", "/the/result/page")

See fullor shortanswers

查看完整简短的答案

回答by Dheeraj Thedijje

Quick Answer

快速回答

Use different methods to load the form and save/process form.

使用不同的方法加载表单和保存/处理表单。

Example.

例子。

Login.php

登录.php

Load login form at Login/indexValidate login at Login/validate

Login/index验证登录时加载登录表单Login/validate

On Success

成功

Redirect the user to User/dashboard

将用户重定向到 User/dashboard

On failure

失败时

Redirect the user to login/index

将用户重定向到 login/index