PHP bir form göndererek, nasıl birden ekler önlemek için?

12 Cevap php

Bazen kullanıcı Enter iki defa basın edebilir ve sonrası iki kez sokulur.

Ile bir yazı varsa zaten kontrol dışında, bu başka önlemek için bir çözüm var mı aynı title ve content?

12 Cevap

Her post / geri gönderme sadece bir kez işlenir, böylece yazı ile eşsiz bir simge kullanın.

Gönder düğmesini devre dışı bırakma insanlar javascript kapalı, ya da başka garip şeyler yapıyor olabilir çünkü çok iyi bir çözüm değildir. İstemci tarafı doğrulama iyi bir başlangıç, ama her zaman sunucu tarafında hem de taşıma ile yedeklenmesi gerekir.

Bu sorunun birkaç çözümü vardır:

  1. Buna Use Javascript to disable the form's submit button when it is posted. Olumsuz bu KESİNLİKLE kusursuz bir yol olmasıdır. Aslında butonuna tıklayarak olmadan formları göndermek çok kolay, ve bu da JavaScript devre dışı kullanıcılar için işe yaramaz. I would definitely not recommend this method.

    Örnek:

    <script language="javascript">
    <!--
        function disableSubmitButton() {
            // you may fill in the blanks :)
        }
    -->
    </script>
    <form action="foo.php" method="post">
        <input type="text" name="bar" />
        <input type="submit" value="Save" onclick="disableSubmitButton();">
    </form>
    
  2. Use PHP sessions yazının geçerli zaman damgası (örnek $ _SESSION ['posttimer'] için) bir oturum değişkeni ayarlamak için. Aslında PHP formu işlemeden önce , kontrol ederseniz $ _SESSION ['posttimer '] değişkeni var ve belli bir zaman damgası fark (IE: 2 saniye) kontrol edin. Bu şekilde, kolayca çift gönderimleri filtre edebilirsiniz.

    Örnek:

    // form.html
    <form action="foo.php" method="post">
        <input type="text" name="bar" />
        <input type="submit" value="Save">
    </form>
    
    
    // foo.php
    if (isset($_POST) && !empty($_POST)) 
    {
        if (isset($_SESSION['posttimer']))
        {
            if ( (time() - $_SESSION['posttimer']) <= 2)
            {
                // less then 2 seconds since last post
            }
            else
            {
                // more than 2 seconds since last post
            }
        }
        $_SESSION['posttimer'] = time();
    }
    
  3. Include a unique token on each POST. Bu durumda, siz de dahil ve sonra formda belirteci işlemek istediğiniz belirteci bir oturum değişkeni ayarlamak olacaktır. Form gönderildikten sonra, simgeyi yeniden-üretir. Sunulan belirteci oturumunda belirteci eşleşmiyor zaman, formu re-teslim edilmiş ve geçersiz ilan edilmelidir.

    Örnek:

    // form.php
    <?php
        // obviously this can be anything you want, as long as it is unique
        $_SESSION['token'] = md5(session_id() . time());
    ?>
    <form action="foo.php" method="post">
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" />
        <input type="text" name="bar" />
        <input type="submit" value="Save" />
    </form>
    
    
    // foo.php
    if (isset($_SESSION['token']))
    {
        if (isset($_POST['token']))
        {
            if ($_POST['token'] != $_SESSION['token'])
            {
                // double submit
            }
        }
    }
    

Formu göndermek için benzersiz, tek kullanımlık anahtarı oluşturun.

Bu kullanıcı tarafından istemci devre dışı bırakılmış olabilir, çünkü JavaScript dayanarak kötü bir fikirdir. Göndermek sunucu tarafından alınan anahtar düzeni ile, bu anahtarın teslim kilitlenmiş olabilir. Sen ancak sizin gibi gönderimleri çoğaltmak yanıt verebilir.

Bu yaklaşım, çalışması için, tuşları benzersiz ve tahmin etmek çok zor olmalı. Aksi takdirde bazı formları nedeniyle önemli çarpışmalar kilitlenmiş olabilir. Yani her form gönderme tuşları izlemek ve çarpışmaları önlemek zorunda değilsiniz, tuşları o kullanıcının oturumu ile sona gerekir. Dikkat etmeniz gereken başka bir şey kötü niyetli kullanıcıların anahtarı tahmin etmek mümkün ise, kod kaçırma veya DOS istismar çeşit savunmasız olabilir olduğunu.

Alternatif olarak, bir defalık formu tuşlarını kullanın.

Ben bunu kullanın:

$form_token = $_SESSION['form_token'] = md5(uniqid());

sonra, formu ile $ form_token gönderebilirsiniz ...

Ben form_token kontrol edin:

if($_SESSION['form_token'] != $_POST['form_token']) {
   echo 'Error';
}

Prevent Duplicate Form Submission javascript olmadan bunu yapmanın bir yol gösterir.

Form teslim alır kez Javascript kullanarak Gönder düğmesini devre dışı bırakın (onsubmit).

Kullanıcı Javascript devre dışı bıraktıysa, yine iki gönderebilirsiniz unutmayın. (Senin soru önerilen gibi) bu sık sık kod denetimi de haklı çıkarmak için yeterli olur olsun ya da size kalmış.

kullanıcı JavaScript kullanarak, formu teslim sonra Gönder düğmesini devre dışı bırakın. Yani bir soruya cevap zaman, örneğin StackOverflow kullandığı, ne olduğunu.

Örneğin

<input type="submit" onclick="this.disabled=true" />

Iki çok nadiren teslim basarak çoklu insert sonuçlanır, ancak bir ölü basit sollution, kullanmak istiyorsanız

onsubmit="document.getElementById('submit').disabled = true"

form etiketi, sen id="submit" sizin gönderme düğmesi vermek İşletmesi

Kısa sürede tıklandığında gibi düğmesini devre dışı bırakmak için bir JavaScript kullanın.

onclick="this.disabled=true;forms[0].submit();"

Göndermeyi durdurmak için JavaScript kullanın

Aron Rotteveel en Include a unique token on each POST benim için çalıştı. Bir kullanıcı sayfası (F5) yeniler Ancak, benim form hala gönderir. Ben bir reset ekleyerek bu çözmek başardı:

            // reset session token
            $_SESSION['token'] = md5( $_POST['token'] . time() );

benim son komut şöyle:

if (isset($_SESSION['token'])) {
    if (isset($_POST['token'])) {
        if ($_POST['token'] != $_SESSION['token']) {
            echo '<h3>Oops! You already submitted this request.</h3>';
        } else {
            // process form
            // reset session token
            $_SESSION['token'] = md5( $_POST['token'] . time() );
        }
    } else {
        echo 'post token not set';
        $_SESSION['token'] = md5( $somevariable . time() );
    }
}

oh! session_start(); önce eklemek unutmayın <!DOCTYPE>

Ben düzensizlikleri bulursanız beni düzeltin lütfen bir PHP çaylağım.