Programming

양식 재 제출 방지

procodes 2020. 8. 14. 21:14
반응형

양식 재 제출 방지


페이지 1에는 HTML 양식이 있습니다. 2 페이지-제출 된 데이터를 처리하는 코드.

1 페이지의 양식이 제출됩니다. 브라우저가 2 페이지로 리디렉션됩니다. 2 페이지는 제출 된 데이터를 처리합니다.

이 시점에서 페이지 2가 새로 고쳐지면 "양식 재 제출 확인"경고가 나타납니다.

이를 방지 할 수 있습니까?


사람들이 여기에서 사용하는 두 가지 접근 방식이 있습니다.

방법 1 : AJAX + 리디렉션 사용

이렇게하면 JQuery 또는 Page2와 유사한 것을 사용하여 백그라운드에서 양식을 게시하는 반면 사용자는 여전히 page1이 표시된 것을 볼 수 있습니다. 게시에 성공하면 브라우저를 Page2로 리디렉션합니다.

방법 2 : 게시 + 자신에게 리디렉션

이것은 포럼에서 일반적인 기술입니다. 페이지 1의 양식은 페이지 2에 데이터를 게시하고, 페이지 2는 데이터를 처리하고 필요한 작업을 수행 한 다음 자체적으로 HTTP 리디렉션을 수행합니다. 이렇게하면 브라우저가 기억하는 마지막 "작업"은 page2의 간단한 GET이므로 F5시 양식이 다시 제출되지 않습니다.


PRG-Post / Redirect / Get 패턴을 사용해야 하며 방금 PRG의 P를 구현했습니다. 리디렉션 해야합니다 . (지금은 리디렉션이 전혀 필요하지 않습니다. 참조 하십시오 )

PRG는 양식 제출 (Post Request 1)-> Redirect-> Get (Request 2)를 의미하는 일부 중복 양식 제출을 방지하는 웹 개발 디자인 패턴입니다.

Under the hood

리디렉션 상태 코드 -HTTP 302를 사용하는 HTTP 1.0 또는 HTTP 303을 사용하는 HTTP 1.1

리디렉션 상태 코드가있는 HTTP 응답은 위치 헤더 필드에 URL을 추가로 제공합니다. 사용자 에이전트 (예 : 웹 브라우저)는이 코드가있는 응답에 의해 초대되어 위치 필드에 지정된 새 URL에 대해 동일한 두 번째 요청을합니다.

리디렉션 상태 코드는이 상황에서 웹 사용자의 브라우저가 초기 HTTP POST 요청을 다시 제출하지 않고도 서버 응답을 안전하게 새로 고칠 수 있도록하는 것입니다.

Double Submit Problem

이중 제출 문제

Post/Redirect/Get Solution

게시 / 리디렉션 / 솔루션 가져 오기

출처


직접적으로 할 수 없습니다. 그것은 좋은 일입니다. 브라우저의 경고는 이유가 있습니다. 이 스레드는 귀하의 질문에 답할 것입니다.

뒤로 버튼이 POST 확인 경고를 표시하지 않도록 방지

제안 된 두 가지 주요 해결 방법은 PRG 패턴과 AJAX 제출 후 스크립팅 재배치였습니다.

Note that if your method allows for a GET and not a POST submission method, then that would both solve the problem and better fit with convention. Those solutions are provided on the assumption you want/need to POST data.


The only way to be 100% sure the same form never gets submitted twice is to embed a unique identifier in each one you issue and track which ones have been submitted at the server. The pitfall there is that if the user backs up to the page where the form was and enters new data, the same form won't work.


There are two parts to the answer:

  1. Ensure duplicate posts don't mess with your data on the server side. To do this, embed a unique identifier in the post so that you can reject subsequent requests server side. This pattern is called Idempotent Receiver in messaging terms.

  2. Ensure the user isn't bothered by the possibility of duplicate submits by both

    • redirecting to a GET after the POST (POST redirect GET pattern)
    • disabling the button using javascript

Nothing you do under 2. will totally prevent duplicate submits. People can click very fast and hackers can post anyway. You always need 1. if you want to be absolutely sure there are no duplicates.


If you refresh a page with POST data, the browser will confirm your resubmission. If you use GET data, the message will not be displayed. You could also have the second page, after saving the submission, redirect to a third page with no data.


Well I found nobody mentioned this trick.

Without redirection, you can still prevent the form confirmation when refresh.

By default, form code is like this:

<form method="post" action="test.php">

now, change it to <form method="post" action="test.php?nonsense=1">

You will see the magic.

I guess its because browsers won't trigger the confirmation alert popup if it gets a GET method (query string) in the url.


The PRG pattern can only prevent the resubmission caused by page refreshing. This is not a 100% safe measure.

Usually, I will take actions below to prevent resubmission:

  1. Client Side - Use javascript to prevent duplicate clicks on a button which will trigger form submission. You can just disable the button after the first click.

  2. Server Side - I will calculate a hash on the submitted parameters and save that hash in session or database, so when the duplicated submission was received we can detect the duplication then proper response to the client. However, you can manage to generate a hash at the client side.

In most of the occasions, these measures can help to prevent resubmission.


@Angelin의 대답을 정말 좋아합니다. 그러나 이것이 실용적이지 않은 레거시 코드를 다루는 경우이 기술이 적합 할 수 있습니다.

파일 상단

// Protect against resubmits
if (empty($_POST))  {
   $_POST['last_pos_sub'] = time();
} else {
     if (isset($_POST['last_pos_sub'])){
        if ($_POST['last_pos_sub'] == $_SESSION['curr_pos_sub']) {
           redirect back to the file so POST data is not preserved
        }
        $_SESSION['curr_pos_sub'] = $_POST['last_pos_sub'];
     }
}

그런 다음 양식 끝에 last_pos_sub다음과 같이 입력하십시오.

<input type="hidden" name="last_pos_sub" value=<?php echo $_POST['last_pos_sub']; ?>>

tris 시도 :

function prevent_multi_submit($excl = "validator") {
    $string = "";
    foreach ($_POST as $key => $val) {
    // this test is to exclude a single variable, f.e. a captcha value
    if ($key != $excl) {
        $string .= $key . $val;
    }
    }
    if (isset($_SESSION['last'])) {
    if ($_SESSION['last'] === md5($string)) {
        return false;
    } else {
        $_SESSION['last'] = md5($string);
        return true;
    }
    } else {
    $_SESSION['last'] = md5($string);
    return true;
    }
}

사용 방법 / 예 :

if (isset($_POST)) {
    if ($_POST['field'] != "") { // place here the form validation and other controls
    if (prevent_multi_submit()) { // use the function before you call the database or etc
        mysql_query("INSERT INTO table..."); // or send a mail like...
        mail($mailto, $sub, $body); // etc
    } else {
        echo "The form is already processed";
    }
    } else {
    // your error about invalid fields
    }
}

글꼴 : https://www.tutdepot.com/prevent-multiple-form-submission/


데이터 추가를 방지하려면 js를 사용하십시오.

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

참고 URL : https://stackoverflow.com/questions/3923904/preventing-form-resubmission

반응형