Cách ngăn chặn gửi lại biểu mẫu khi trang được làm mới (F5 / CTRL + R)


131

Tôi có một hình thức đơn giản để gửi văn bản vào bảng SQL của tôi. Vấn đề là sau khi người dùng gửi văn bản, họ có thể làm mới trang và dữ liệu sẽ được gửi lại mà không cần điền lại biểu mẫu. Tôi có thể chuyển hướng người dùng đến một trang khác sau khi văn bản được gửi, nhưng tôi muốn người dùng ở cùng một trang.

Tôi nhớ đã đọc một cái gì đó về việc cung cấp cho mỗi người dùng một id phiên duy nhất và so sánh nó với một giá trị khác giải quyết vấn đề tôi đang gặp phải nhưng tôi quên mất nó ở đâu.



1
Tại sao bạn không muốn chuyển hướng người dùng đến một trang khác?
Adam

@Adam: Bởi vì điều này là quá mức để thực hiện một yêu cầu khác đến máy chủ, lần lượt sẽ lấy lại một số dữ liệu từ DB. Nhưng đây là sự lãng phí tài nguyên vì chúng tôi đã lấy tất cả dữ liệu cần thiết trong khi xử lý POSTyêu cầu
Eugen Konkov

@EugenKonkov trong mẫu PRG, bạn sẽ chỉ chuyển hướng đến một trang hiển thị thông báo thành công. Không cần tìm nạp thêm từ DB.
Adam

@Adam: Bạn cũng có thể hiển thị toàn bộ hồ sơ được tạo bằng cách nhập POSTdữ liệu. Trong trường hợp này, bạn cần SELECTnó từ DB. Ví dụ: khi bạn tạo hóa đơn, bạn được chuyển hướng đến /invoices/53đó sẽ hiển thị toàn bộ hóa đơn thay vì chỉ 'thành công'
Eugen Konkov

Câu trả lời:


95

Sử dụng mẫu Đăng / Chuyển hướng / Nhận. http://en.wikipedia.org/wiki/Post/Redirect/Get

Với trang web của tôi, tôi sẽ lưu trữ một tin nhắn trong cookie hoặc phiên, chuyển hướng sau bài đăng, đọc cookie / phiên và sau đó xóa giá trị của phiên hoặc biến cookie đó.


1
Điều này làm cho chrome không thể sử dụng để phát triển trong đó doanh nghiệp chỉ cần một bài đăng!
John Peters

26
Nếu bạn sử dụng mẫu PRG, thì bạn thực sự rời khỏi trang phải không? Không phải là câu hỏi làm thế nào để làm cho mọi thứ hoạt động khi không chuyển hướng?
Adam

Dường như với tôi rằng nếu bạn chuyển hướng đến cùng một trang, thì $ _POST sẽ bị xóa. Theo tôi hiểu, đó là hiệu quả mong muốn. Dù sao đó cũng là hiệu quả mong muốn của tôi. Tôi nghĩ rằng câu trả lời sẽ tốt hơn nếu nó được làm rõ ràng, mặc dù.
donutguy640

Hoạt động tốt, khuyến nghị duy nhất của tôi là đảm bảo bạn kích hoạt kiểm tra lỗi nghiêm ngặt để bạn bắt lỗi cục bộ trong khi phát triển, nếu không chúng có thể không được chú ý.
Maurice

Không trả lời câu hỏi. Không chắc tại sao đó là câu trả lời được chấp nhận.
YungGun

124

Tôi cũng muốn chỉ ra rằng bạn có thể sử dụng cách tiếp cận javascript, window.history.replaceStateđể ngăn việc gửi lại trên nút làm mới và quay lại.

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

Bằng chứng về khái niệm ở đây: https://dtbaker.net/files/prevent-post-resubmit.php

Tôi vẫn sẽ đề xuất một cách tiếp cận Post / Redirect / Get, nhưng đây là một giải pháp JS mới lạ.


1
Cảm ơn, @dtbaker, thật tuyệt vời :)
Gufran Hasan

1
Tks, đây là công việc hoàn hảo đối với tôi, nó chỉ cần tạo trang 404 để tránh sự hiểu lầm của người dùng
tess hsu

Đơn giản là tuyệt vời. Thankyou
user4906240

2
Nó không hoạt động ở safari, nó đã thay đổi href nhưng vẫn giữ dữ liệu với yêu cầu gửi
Võ Thanh Tung

Điều này làm việc cho tôi cảm ơn bạn! Tại sao bạn đề xuất phương pháp PRG?
iJassar

16

Bạn thực sự nên sử dụng mẫu Chuyển hướng bài đăng để xử lý việc này nhưng nếu bạn bằng cách nào đó đã kết thúc ở một vị trí mà PRG không khả thi (ví dụ: chính biểu mẫu nằm trong một bao gồm, ngăn chuyển hướng), bạn có thể băm một số tham số yêu cầu để tạo một chuỗi dựa trên nội dung và sau đó kiểm tra xem bạn đã gửi nó chưa.

//create digest of the form submission:

    $messageIdent = md5($_POST['name'] . $_POST['email'] . $_POST['phone'] . $_POST['comment']);

//and check it against the stored value:

    $sessionMessageIdent = isset($_SESSION['messageIdent'])?$_SESSION['messageIdent']:'';

    if($messageIdent!=$sessionMessageIdent){//if its different:          
        //save the session var:
            $_SESSION['messageIdent'] = $messageIdent;
        //and...
            do_your_thang();
    } else {
        //you've sent this already!
    }

Cảm ơn đã chia sẻ nhưng điều này dường như không hoạt động. Làm mới trang thực sự gửi lại mẫu cho tôi. Có lẽ tôi đang thiếu một cái gì đó?
aLearner

Làm mới trang sẽ gửi lại mọi thứ nhưng chúng tôi chỉ chọn xử lý dữ liệu gửi nếu nó khác với dữ liệu được gửi lần trước (mà chúng tôi lưu trữ trong phiên var 'messageIdent'). Bạn có đang xử lý việc gửi biểu mẫu của mình trong mệnh đề 'if messageIdents khác nhau không (nghĩa là' do_your_thang () ')?
Moob

Cảm ơn vì đã trả lời. Cuối cùng tôi chỉ thực hiện mô hình Đăng / Chuyển hướng / Nhận, vì vậy, bây giờ tôi không nhớ chính xác điều gì đã làm tôi vấp ngã. Cảm ơn một lần nữa cho vòng tròn trở lại, mặc dù.
aLearner

Phương pháp này không có nghĩa là chặn gửi lại ... nhưng để Phát hiện gửi lại để bạn có thể thay đổi mã của mình thành không "làm" bất cứ điều gì bạn sẽ làm nếu đây là một bài nộp mới. Nói cách khác: Với phương pháp này, bạn có thể phát hiện việc gửi "bản gốc" và đặt dữ liệu của mình. Nếu nó KHÔNG phải là bản gốc, đừng đặt dữ liệu của bạn. Thay vào đó, hiển thị cảnh báo "cố gắng lừa đảo" hoặc có thể hiển thị "xác nhận".
TheSatinKnight

Để làm việc này, bạn phải bắt đầu một phiên bằng cách thêm session_start();vào đầu tệp. w3schools.com/php/php_simes.asp nói Lưu ý: Hàm session_start () phải là thứ đầu tiên trong tài liệu của bạn. Trước bất kỳ thẻ HTML nào.
wkille

16

Tôi sử dụng dòng javascript này để chặn cửa sổ bật lên yêu cầu gửi lại biểu mẫu khi được làm mới sau khi biểu mẫu được gửi.

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

Chỉ cần đặt dòng này ở chân trang của tập tin của bạn và xem phép thuật


Sẽ là một phiên bản tốt đẹp không thể bị vô hiệu hóa từ phía khách hàng, nhưng nó ngắn, dễ dàng, nhanh chóng ... và làm những gì nó cần làm. Giữ lịch sử để người dùng có thể điều hướng trở lại, mà không cần gửi lại bài.
Péter Vértényi

16

Bạn có thể ngăn việc gửi lại biểu mẫu thông qua một biến phiên.

Trước tiên, bạn phải đặt rand()trong một hộp văn bản và $_SESSION['rand']trên trang mẫu:

<form action="" method="post">
  <?php
   $rand=rand();
   $_SESSION['rand']=$rand;
  ?>
 <input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
   Your Form's Other Field 
 <input type="submit" name="submitbtn" value="submit" />
</form>

Sau đó kiểm tra $_SESSION['rand']với $_POST['randcheck']giá trị hộp văn bản như thế này:

if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
{
    // Your code here
}

3
chúng ta có thể sử dụng <input type="hidden" name="randcheck" id="randcheck" value="<?php echo microtime(); ?>" />thay thế
Nikolay Bronskiy

Có, chúng ta có thể sử dụng microtime () cũng như time () thay vì rand (), bất kỳ hàm hoặc biến nào mang lại giá trị khác nhau, chúng ta có thể sử dụng nó. NHƯNG đảm bảo rằng bạn đặt giá trị đó thành biến SESSION. Ở đây SESSION phải kiểm tra với trường randcheck và để ngăn chặn gửi lại mẫu.
Savoo

biến phiên có nên bị xóa sau khi kiểm tra xem phiên và bài đăng có khớp không?
denùa

1
@denoir Tôi tin rằng ý tưởng của @Savoo là sau khi $_POSTdữ liệu biểu mẫu, cùng một trang tải lại cài đặt lại các phiên và các biến đăng. Ngoài ra việc tạo các biến sẽ diễn ra sau khi kiểm tra xem các biến đó có khớp không. Do đó unsetkhông cần thiết.
HalfMens

13

Khi biểu mẫu được xử lý, bạn chuyển hướng đến một trang khác:

... process complete....
header('Location: thankyou.php');

bạn cũng có thể chuyển hướng đến cùng một trang.

nếu bạn đang làm một cái gì đó như bình luận và bạn muốn người dùng ở cùng một trang, bạn có thể sử dụng Ajax để xử lý việc gửi biểu mẫu


12

Tôi tìm thấy cách giải quyết tiếp theo. Bạn có thể thoát khỏi chuyển hướng sau khi xử lý POSTyêu cầu bằng cách thao tác historyđối tượng.

Vì vậy, bạn có dạng HTML:

<form method=POST action='/process.php'>
 <input type=submit value=OK>
</form>

Khi bạn xử lý biểu mẫu này trên máy chủ của mình, bạn thay vì chuyển hướng người dùng đến /the/result/pagebằng cách thiết lập Locationtiêu đề như thế này:

$cat process.php
<?php 
     process POST data here
     ... 
     header('Location: /the/result/page');
     exit();
?>

nhập mô tả hình ảnh ở đây

Sau khi xử lý POSTdữ liệu ed, bạn kết xuất nhỏ <script>và kết quả/the/result/page

<?php 
     process POST data here
     render the <script>         // see below
     render `/the/result/page`   // OK
?>

Các <script>bạn nên làm:

<script>
    window.onload = function() {
        history.replaceState("", "", "/the/result/page");
    }
</script>

Kết quả là:

nhập mô tả hình ảnh ở đây

như bạn có thể thấy dữ liệu biểu mẫu được POSTchuyển thành process.phptập lệnh.
Kịch bản lệnh này xử lý POSTdữ liệu ed và kết xuất /the/result/pagecùng một lúc với:

  1. không chuyển hướng
  2. không có POSTdữ liệu lại khi bạn làm mới trang (F5)
  3. không gặp lại POSTkhi bạn điều hướng đến trang trước / trang tiếp theo thông qua lịch sử trình duyệt

CẬP NHẬT

Như một giải pháp khác, tôi yêu cầu tính năng yêu cầu nhóm Mozilla FireFox cho phép người dùng thiết lập NextPagetiêu đề sẽ hoạt động giống như Locationtiêu đề và làm cho post/redirect/getmẫu bị lỗi thời.

Nói ngắn gọn. Khi máy chủ xử lý POSTdữ liệu mẫu thành công, nó:

  1. Thiết lập NextPagetiêu đề thay vìLocation
  2. Kết xuất kết quả xử lý POSTdữ liệu biểu mẫu vì nó sẽ hiển thị cho GETyêu cầu theo post/redirect/getmẫu

Trình duyệt lần lượt khi thấy NextPagetiêu đề:

  1. Điều chỉnh window.locationtheo NextPagegiá trị
  2. Khi người dùng làm mới trang, trình duyệt sẽ thương lượng GETyêu cầu NextPagethay vì tạo lại POSTdữ liệu

Tôi nghĩ rằng điều này sẽ xuất sắc nếu được thực hiện, phải không? =)


11
  1. Sử dụng tiêu đề và chuyển hướng trang.

    header("Location:your_page.php"); Bạn có thể chuyển hướng đến cùng một trang hoặc trang khác.

  2. Bỏ đặt $ _POST sau khi chèn nó vào Cơ sở dữ liệu.

    unset($_POST);


54
Bỏ cài đặt $ _POST hoàn toàn không ảnh hưởng đến việc gửi lại biểu mẫu, ít nhất là không có trong Chrome.
Gavin

2
Nó sẽ không làm việc. Khi người dùng quay lại trang, nó thực hiện thiết lập các biến POST một lần nữa.
Sandhu

Lý do của việc sử dụng là unsetgì? Vui lòng thêm một số lời giải thích cho câu trả lời của bạn để những người khác có thể học hỏi từ nó
Nico Haase

7

Một cách khá chắc chắn là triển khai một ID duy nhất vào bài đăng và lưu nó vào trong

<input type='hidden' name='post_id' value='".createPassword(64)."'>

Sau đó, trong mã của bạn làm điều này:

if( ($_SESSION['post_id'] != $_POST['post_id']) )
{
    $_SESSION['post_id'] = $_POST['post_id'];
    //do post stuff
} else {
    //normal display
}

function createPassword($length)
{
    $chars = "abcdefghijkmnopqrstuvwxyz023456789";
    srand((double)microtime()*1000000);
    $i = 0;
    $pass = '' ;

    while ($i <= ($length - 1)) {
        $num = rand() % 33;
        $tmp = substr($chars, $num, 1);
        $pass = $pass . $tmp;
        $i++;
    }
    return $pass;
}

Tôi thực sự chỉ viết một cái gì đó tương tự như thế này, nhưng không gặp rắc rối khi tạo mật khẩu, tôi chỉ liệt kê các biểu mẫu của mình (ví dụ: các bước 1-5), vì vậy nếu chúng bằng nhau, chúng ta sẽ rất tuyệt khi tiếp tục, khác không lưu vào db hoặc gửi email. Nhưng hãy để người dùng hạ cánh bất cứ nơi nào nó đưa anh ta.
Fernando Silva

1
Tôi nghĩ rằng đây là một giải pháp tốt hơn so với tải lại trang, vì tôi hiển thị một thông báo khi đăng thành công và tải lại trang sẽ xóa tin nhắn. công việc này rất tốt cho tôi, bạn cũng có thể sử dụng một uniqid
Julio Popócatl

6

Phương pháp này hiệu quả với tôi và tôi nghĩ đây là cách đơn giản nhất để thực hiện công việc này.

Ý tưởng chung là chuyển hướng người dùng đến một số trang khác sau khi gửi biểu mẫu, điều này sẽ dừng việc gửi lại biểu mẫu khi làm mới trang. Tuy nhiên, nếu bạn cần giữ người dùng trên cùng một trang sau khi biểu mẫu được gửi, bạn có thể thực hiện theo nhiều cách, nhưng ở đây tôi đang mô tả phương pháp javascript.

Phương pháp Javascript

Phương pháp này khá dễ dàng và chặn cửa sổ bật lên yêu cầu gửi lại biểu mẫu khi được làm mới sau khi biểu mẫu được gửi. Chỉ cần đặt dòng mã javascript này ở chân trang của tệp của bạn và xem điều kỳ diệu.

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


Điều này cũng giúp tôi
Ankit

4

Javascript

Phương pháp này khá dễ dàng và chặn cửa sổ bật lên yêu cầu gửi lại biểu mẫu khi được làm mới sau khi biểu mẫu được gửi. Chỉ cần đặt dòng mã javascript này ở chân trang của tệp của bạn và xem điều kỳ diệu.

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

3

Chỉ cần chuyển hướng nó đến cùng một trang sau khi sử dụng dữ liệu biểu mẫu và nó hoạt động. Tôi đã thử nó.

header('location:yourpage.php');

4
Đây chỉ là lặp lại cùng một câu trả lời mà người khác đã đưa ra nhiều năm trước đó. (Trên thực tế là hai người khác!)
Nick Rice

Nếu bạn sao chép câu trả lời của người khác, ít nhất bạn nên thêm một số lời giải thích cho câu trả lời của mình để khiến nó trở nên thú vị
Nico Haase

3

Một phiên bản tinh tế của bài viết của Moob. Tạo một hàm băm của POST, lưu nó dưới dạng cookie phiên và so sánh băm mỗi phiên.

// Optionally Disable browser caching on "Back"
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Expires: Sun, 1 Jan 2000 12:00:00 GMT' );
header( 'Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT' );

$post_hash = md5( json_encode( $_POST ) );

if( session_start() )
{
    $post_resubmitted = isset( $_SESSION[ 'post_hash' ] ) && $_SESSION[ 'post_hash' ] == $post_hash;
    $_SESSION[ 'post_hash' ] = $post_hash;
    session_write_close();
}
else
{
    $post_resubmitted = false;
}

if ( $post_resubmitted ) {
  // POST was resubmitted
}
else
{
  // POST was submitted normally
}

2

Về cơ bản, bạn cần chuyển hướng ra khỏi trang đó nhưng nó vẫn có thể gây ra sự cố trong khi internet của bạn chậm (Chuyển hướng tiêu đề từ máy chủ)

Ví dụ về kịch bản cơ bản:

Nhấp vào nút gửi hai lần

Cách giải quyết

  • Phía khách hàng

    • Vô hiệu hóa nút gửi khi khách hàng nhấp vào nó
    • Nếu bạn sử dụng Jquery: Jquery.one
    • Mẫu PRG
  • Phía máy chủ

    • Sử dụng dấu thời gian băm dựa trên dấu thời gian / dấu thời gian khác nhau khi yêu cầu được gửi.
    • Mã thông báo vô dụng. Khi tải chính lên chỉ định một mã thông báo yêu cầu tạm thời mà nếu lặp lại sẽ bị bỏ qua.

2

Làm thế nào để ngăn chặn việc gửi lại biểu mẫu php mà không cần chuyển hướng. Nếu bạn đang sử dụng $ _SESSION (sau session_start) và biểu mẫu $ _POST, bạn có thể làm một cái gì đó như thế này:

if ( !empty($_SESSION['act']) && !empty($_POST['act']) && $_POST['act'] == $_SESSION['act'] ) {
  // do your stuff, save data into database, etc
}

Trong mẫu html của bạn, hãy đặt cái này:

<input type="hidden" id="act" name="act" value="<?php echo ( empty($_POST['act']) || $_POST['act']==2 )? 1 : 2; ?>">
<?php
if ( $_POST['act'] == $_SESSION['act'] ){
    if ( empty( $_SESSION['act'] ) || $_SESSION['act'] == 2 ){
        $_SESSION['act'] = 1;
    } else {
        $_SESSION['act'] = 2;
    }
}
?>

Vì vậy, mỗi khi biểu mẫu được gửi, một hành động mới được tạo ra, được lưu trữ trong phiên và được so sánh với hành động đăng.

Ps: nếu bạn đang sử dụng biểu mẫu Nhận, bạn có thể dễ dàng thay đổi tất cả POST bằng GET và nó cũng hoạt động.


1

Sau khi chèn nó vào cơ sở dữ liệu, hãy gọi phương thức unset () để xóa dữ liệu.

bỏ đặt ($ _ POST);

Để ngăn việc chèn dữ liệu làm mới, hãy thực hiện chuyển hướng trang đến cùng một trang hoặc trang khác sau khi chèn bản ghi.

tiêu đề ('Vị trí:'. $ _ SERVER ['PHP_SELF']);


1
Vui lòng thêm một số lời giải thích cho câu trả lời của bạn để người khác có thể học hỏi từ nó - tại sao unsetcuộc gọi đó lại cần thiết? Điều gì sẽ xảy ra nếu bạn bỏ qua nó?
Nico Haase

0

Sử dụng mẫu Đăng / Chuyển hướng / Nhận từ câu trả lời của Keverw là một ý tưởng hay. Tuy nhiên, bạn không thể ở lại trang của mình (và tôi nghĩ đây là những gì bạn đang yêu cầu?) Ngoài ra, đôi khi có thể thất bại :

Nếu người dùng web làm mới trước khi quá trình gửi ban đầu hoàn tất do máy chủ bị lag, dẫn đến yêu cầu POST HTTP trùng lặp trong các tác nhân người dùng nhất định.

Một tùy chọn khác sẽ là lưu trữ trong một phiên nếu văn bản phải được ghi vào cơ sở dữ liệu SQL của bạn như thế này:

if($_SERVER['REQUEST_METHOD'] != 'POST')
{
  $_SESSION['writeSQL'] = true;
}
else
{
  if(isset($_SESSION['writeSQL']) && $_SESSION['writeSQL'])
  {
    $_SESSION['writeSQL'] = false;

    /* save $_POST values into SQL */
  }
}

0

Như những người khác đã nói, không thể sử dụng post / redirect / get. Nhưng đồng thời cũng khá dễ dàng để làm những gì bạn muốn làm phía máy chủ.

Trong trang POST của bạn, bạn chỉ cần xác thực đầu vào của người dùng nhưng không hành động trên nó, thay vào đó bạn sao chép nó vào một mảng SESSION. Sau đó, bạn chuyển hướng trở lại trang trình chính một lần nữa. Trang gửi chính của bạn bắt đầu bằng cách kiểm tra xem liệu mảng SESSION mà bạn đang sử dụng có tồn tại hay không, và nếu vậy hãy sao chép nó vào một mảng cục bộ và bỏ đặt nó. Từ đó bạn có thể hành động trên nó.

Bằng cách này, bạn chỉ làm tất cả công việc chính của mình một lần, đạt được những gì bạn muốn làm.


0

Tôi đã tìm kiếm giải pháp để ngăn chặn việc gửi lại trong một dự án lớn sau đó. Mã này hoạt động rất tốt với $ _GET và $ _POST và tôi không thể thay đổi hành vi của các thành phần biểu mẫu mà không có nguy cơ xảy ra lỗi không lường trước được. Vì vậy, đây là mã của tôi:

<!-- language: lang-php -->
<?php

// Very top of your code:

// Start session:
session_start();

// If Post Form Data send and no File Upload
if ( empty( $_FILES ) && ! empty( $_POST ) ) {
    // Store Post Form Data in Session Variable
    $_SESSION["POST"] = $_POST;
    // Reload Page if there were no outputs
    if ( ! headers_sent() ) {
        // Build URL to reload with GET Parameters
        // Change https to http if your site has no ssl
        $location = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        // Reload Page
        header( "location: " . $location, true, 303 );
        // Stop any further progress
        die();
    }
}

// Rebuilt POST Form Data from Session Variable
if ( isset( $_SESSION["POST"] ) ) {
    $_POST = $_SESSION["POST"];
    // Tell PHP that POST is sent
    $_SERVER['REQUEST_METHOD'] = 'POST';
}

// Your code:
?><html>
    <head>
        <title>GET/POST Resubmit</title>
    </head>
    <body>

    <h1>Forms:</h1>
    <h2>GET Form:</h2>
    <form action="index.php" method="get">
        <input type="text" id="text_get" value="test text get" name="text_get"/>
        <input type="submit" value="submit">
    </form>
    <h2>POST Form:</h2>
    <form action="index.php" method="post">
        <input type="text" id="text_post" value="test text post" name="text_post"/>
        <input type="submit" value="submit">
    </form>
    <h2>POST Form with GET action:</h2>
    <form action="index.php?text_get2=getwithpost" method="post">
        <input type="text" id="text_post2" value="test text get post" name="text_post2"/>
        <input type="submit" value="submit">
    </form>
    <h2>File Upload Form:</h2>
    <form action="index.php" method="post" enctype="multipart/form-data">
        <input type="file" id="file" name="file">
        <input type="submit" value="submit">
    </form>

    <h1>Results:</h1>
    <h2>GET Form Result:</h2>
    <p>text_get: <?php echo $_GET["text_get"]; ?></p>
    <h2>POST Form Result:</h2>
    <p>text_post: <?php echo $_POST["text_post"]; ?></p>
    <h2>POST Form with GET Result:</h2>
    <p>text_get2: <?php echo $_GET["text_get2"]; ?></p>
    <p>text_post2: <?php echo $_POST["text_post2"]; ?></p>
    <h2>File Upload:</h2>
    <p>file:
    <pre><?php if ( ! empty( $_FILES ) ) {
            echo print_r( $_FILES, true );
        } ?></pre>
    </p>
    <p></p>
    </body>
    </html><?php
// Very Bottom of your code:
// Kill Post Form Data Session Variable, so User can reload the Page without sending post data twice
unset( $_SESSION["POST"] );

Nó chỉ hoạt động để tránh gửi lại $ _POST, không phải $ _GET. Nhưng đây là hành vi tôi cần. Vấn đề gửi lại không hoạt động với tải lên tập tin!


0

Những gì làm việc cho tôi là:

if ( !refreshed()) {
   //Your Submit Here
        if (isset( $_GET['refresh'])) {
            setcookie("refresh",$_GET['refresh'], time() + (86400 * 5), "/");
        }

    }    
}


function refreshed()
{
    if (isset($_GET['refresh'])) {
        $token = $_GET['refresh'];
        if (isset($_COOKIE['refresh'])) {
            if ($_COOKIE['refresh'] != $token) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}  


function createToken($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

?>

Và trong mẫu của bạn

 <form  action="?refresh=<?php echo createToken(3)?>">



 </form>

-2
if (($_SERVER['REQUEST_METHOD'] == 'POST') and (isset($_SESSION['uniq']))){
    if($everything_fine){
        unset($_SESSION['uniq']);
    }
}
else{
    $_SESSION['uniq'] = uniqid();
}

Vui lòng thêm một số lời giải thích cho câu trả lời của bạn để những người khác có thể học hỏi từ nó - nó $everything_fineđến từ đâu?
Nico Haase

-3

Tại sao không chỉ sử dụng $_POST['submit']biến như một câu lệnh logic để lưu bất cứ thứ gì có trong biểu mẫu. Bạn luôn có thể chuyển hướng đến cùng một trang (Trong trường hợp họ làm mới, và khi họ nhấn go backtrong trình duyệt, nộp bài biến sẽ không được thiết lập nữa. Chỉ cần chắc chắn nút gửi của bạn có một nameidcủa submit.


1
Hãy xem en.wikipedia.org/wiki/Post/Redirect/Get ! Đây là cách tiếp cận đúng
jan267
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.