บางครั้งเมื่อการตอบกลับช้าอาจมีการคลิกปุ่มส่งหลายครั้ง
จะป้องกันไม่ให้เกิดขึ้นได้อย่างไร?
บางครั้งเมื่อการตอบกลับช้าอาจมีการคลิกปุ่มส่งหลายครั้ง
จะป้องกันไม่ให้เกิดขึ้นได้อย่างไร?
คำตอบ:
ใช้จาวาสคริปต์ที่ไม่สร้างความรำคาญเพื่อปิดใช้งานการส่งเหตุการณ์ในแบบฟอร์มหลังจากที่ส่งไปแล้ว นี่คือตัวอย่างการใช้ jQuery
แก้ไข: แก้ไขปัญหาในการส่งแบบฟอร์มโดยไม่คลิกปุ่มส่ง ขอบคุณ ichiban
$("body").on("submit", "form", function() {
    $(this).submit(function() {
        return false;
    });
    return true;
});
return true? ฉันคิดว่าการส่งครั้งแรกควรใช้งานได้หากไม่มีสิ่งนั้น
                    return trueโดยนัยหากละเว้น
                    $(this).find("input[type='submit']").attr('disabled', 'disabled').val('submiting');     return true; });
                    ฉันลองใช้โซลูชันของ vansteeพร้อมกับการตรวจสอบความถูกต้องของ asp mvc 3 ที่ไม่สร้างความรำคาญและหากการตรวจสอบความถูกต้องของไคลเอ็นต์ล้มเหลวโค้ดจะยังคงทำงานอยู่และการส่งแบบฟอร์มจะถูกปิดใช้งาน ฉันไม่สามารถส่งใหม่ได้หลังจากแก้ไขช่องแล้ว (ดูความคิดเห็นของ bjan)
ดังนั้นฉันจึงแก้ไขสคริปต์ของ vanstee ดังนี้:
$("form").submit(function () {
    if ($(this).valid()) {
        $(this).submit(function () {
            return false;
        });
        return true;
    }
    else {
        return false;
    }
});
การควบคุมการส่งแบบฟอร์มฝั่งไคลเอ็นต์สามารถทำได้อย่างสวยงามโดยให้ตัวจัดการ onsubmit ซ่อนปุ่มส่งและแทนที่ด้วยภาพเคลื่อนไหวการโหลด ด้วยวิธีนี้ผู้ใช้จะได้รับการตอบสนองด้วยภาพทันทีในจุดเดียวกับที่การกระทำของเขา (การคลิก) เกิดขึ้น ในขณะเดียวกันคุณก็ป้องกันไม่ให้ส่งแบบฟอร์มในครั้งอื่น
หากคุณส่งแบบฟอร์มผ่าน XHR โปรดทราบว่าคุณต้องจัดการข้อผิดพลาดในการส่งด้วยเช่นการหมดเวลา คุณจะต้องแสดงปุ่มส่งอีกครั้งเนื่องจากผู้ใช้ต้องการส่งแบบฟอร์มอีกครั้ง
ในหมายเหตุอื่น llimllib เป็นจุดที่ถูกต้องมาก การตรวจสอบแบบฟอร์มทั้งหมดจะต้องเกิดขึ้นที่ฝั่งเซิร์ฟเวอร์ ซึ่งรวมถึงการตรวจสอบการส่งหลายรายการ อย่าไว้ใจลูกค้า! นี่ไม่ใช่เฉพาะกรณีที่จาวาสคริปต์ถูกปิดใช้งาน คุณต้องทราบว่าโค้ดฝั่งไคลเอ็นต์ทั้งหมดสามารถแก้ไขได้ มันค่อนข้างยากที่จะจินตนาการ แต่ html / javascript ที่คุยกับเซิร์ฟเวอร์ของคุณไม่จำเป็นต้องเป็น html / javascript ที่คุณเขียน
ตามที่ llimllib แนะนำให้สร้างแบบฟอร์มด้วยตัวระบุที่ไม่ซ้ำกันสำหรับแบบฟอร์มนั้นและใส่ไว้ในฟิลด์อินพุตที่ซ่อนอยู่ จัดเก็บตัวระบุนั้น เมื่อรับข้อมูลแบบฟอร์มจะประมวลผลเมื่อตัวระบุตรงกันเท่านั้น (เชื่อมโยงตัวระบุกับเซสชันผู้ใช้ด้วยและจับคู่ข้อมูลนั้นด้วยเพื่อความปลอดภัยเป็นพิเศษ) หลังจากการประมวลผลข้อมูลจะลบตัวระบุ
แน่นอนว่านาน ๆ ครั้งคุณจะต้องล้างตัวระบุที่ไม่เคยส่งข้อมูลในรูปแบบใด ๆ แต่ส่วนใหญ่แล้วเว็บไซต์ของคุณอาจใช้กลไก "เก็บขยะ" อยู่แล้ว
<form onsubmit="if(submitted) return false; submitted = true; return true">
<form onsubmit="return (typeof submitted == 'undefined') ? (submitted = true) : !submitted">หรือการเขียนที่จุดทางขวาของสคริปต์ของคุณเพื่อหลีกเลี่ยงข้อผิดพลาดต่อไปนี้:var submitted = false; Uncaught ReferenceError: submitted is not defined
                    วิธีง่ายๆในการทำมีดังนี้
<form onsubmit="return checkBeforeSubmit()">
  some input:<input type="text">
  <input type="submit" value="submit" />
</form>
<script type="text/javascript">
  var wasSubmitted = false;    
    function checkBeforeSubmit(){
      if(!wasSubmitted) {
        wasSubmitted = true;
        return wasSubmitted;
      }
      return false;
    }    
</script>
ปิดใช้งานปุ่มส่งไม่นานหลังจากคลิก ตรวจสอบให้แน่ใจว่าคุณจัดการการตรวจสอบความถูกต้องอย่างเหมาะสม เก็บเพจกลางสำหรับการประมวลผลหรือการดำเนินการ DB ทั้งหมดจากนั้นเปลี่ยนเส้นทางไปยังหน้าถัดไป วิธีนี้ทำให้แน่ใจว่าการรีเฟรชหน้าที่สองจะไม่ทำการประมวลผลอื่น
form page ---submits to---> form_submission_script.php ---after saving, redirects to---> form_thankyou.html
                    แฮชเวลาปัจจุบันทำให้เป็นอินพุตที่ซ่อนอยู่ในแบบฟอร์ม ที่ฝั่งเซิร์ฟเวอร์ตรวจสอบแฮชของการส่งแบบฟอร์มแต่ละครั้ง หากคุณได้รับแฮชนั้นแล้วคุณจะต้องส่งซ้ำ
แก้ไข: การใช้ javascript ไม่ใช่ความคิดที่ดีดังนั้นคุณทุกคนสามารถโหวตแนวคิดเหล่านั้นต่อไปได้ แต่ผู้ใช้บางคนจะไม่เปิดใช้งาน คำตอบที่ถูกต้องคืออย่าเชื่อถืออินพุตของผู้ใช้ทางฝั่งเซิร์ฟเวอร์
คุณยังสามารถแสดงแถบความคืบหน้าหรือตัวหมุนเพื่อระบุว่ากำลังประมวลผลแบบฟอร์ม
การใช้ JQuery คุณสามารถทำได้:
$('input:submit').click( function() { this.disabled = true } );
&
   $('input:submit').keypress( function(e) {
     if (e.which == 13) {
        this.disabled = true 
     } 
    }
   );
ฉันรู้ว่าคุณติดแท็กคำถามของคุณด้วย 'javascript' แต่นี่คือวิธีแก้ปัญหาที่ไม่ขึ้นอยู่กับจาวาสคริปต์เลย:
เป็นรูปแบบเว็บแอปชื่อPRGและนี่คือบทความดีๆที่อธิบาย
คุณสามารถป้องกันการส่งหลายครั้งได้ง่ายๆด้วย:
var Workin = false;
$('form').submit(function()
{
   if(Workin) return false;
   Workin =true;
   // codes here.
   // Once you finish turn the Workin variable into false 
   // to enable the submit event again
   Workin = false;
});
Workin =true;ปัญหาเกี่ยวกับคำตอบของคุณคือการที่มีสองแยกระหว่างเวลาที่ผู้ใช้คลิกที่และเวลา การส่งซ้ำยังทำได้ แต่มีโอกาสน้อยกว่า
                    คำตอบที่ง่ายที่สุดสำหรับคำถามนี้ตามที่ถาม: "บางครั้งเมื่อคำตอบช้าอาจมีคนคลิกปุ่มส่งหลายครั้งจะป้องกันไม่ให้เกิดเหตุการณ์นี้ได้อย่างไร"
เพียงปิดการใช้งานปุ่มส่งแบบฟอร์มเช่นรหัสด้านล่าง
<form ... onsubmit="buttonName.disabled=true; return true;">
  <input type="submit" name="buttonName" value="Submit">
</form>
จะปิดใช้งานปุ่มส่งเมื่อคลิกครั้งแรกเพื่อส่ง นอกจากนี้หากคุณมีกฎการตรวจสอบความถูกต้องก็จะใช้งานได้ดี หวังว่ามันจะช่วยได้
ในฝั่งไคลเอ็นต์คุณควรปิดใช้งานปุ่มส่งเมื่อส่งแบบฟอร์มด้วยรหัสจาวาสคริปต์เช่นเดียวกับวิธีการที่ @vanstee และ @chaos ให้ไว้
แต่มีปัญหาเกี่ยวกับความล่าช้าของเครือข่ายหรือสถานการณ์ที่ปิดใช้งานจาวาสคริปต์ซึ่งคุณไม่ควรพึ่งพา JS เพื่อป้องกันไม่ให้สิ่งนี้เกิดขึ้น
ดังนั้นในฝั่งเซิร์ฟเวอร์คุณควรตรวจสอบการส่งซ้ำจากไคลเอนต์เดียวกันและละเว้นการส่งซ้ำซึ่งดูเหมือนว่าเป็นความพยายามที่ผิดพลาดจากผู้ใช้
คุณสามารถลองใช้ปลั๊กอินSafeform jquery
$('#example').safeform({
    timeout: 5000, // disable form on 5 sec. after submit
    submit: function(event) {
        // put here validation and ajax stuff...
        // no need to wait for timeout, re-enable the form ASAP
        $(this).safeform('complete');
        return false;
    }
})
วิธีแก้ปัญหาที่ง่ายและสง่างามที่สุดสำหรับฉัน:
function checkForm(form) // Submit button clicked
{
    form.myButton.disabled = true;
    form.myButton.value = "Please wait...";
    return true;
}
<form method="POST" action="..." onsubmit="return checkForm(this);">
    ...
    <input type="submit" name="myButton" value="Submit">
</form>
ใช้รหัสนี้ในแบบฟอร์มของคุณซึ่งจะรองรับการคลิกหลายครั้ง
<script type="text/javascript">
    $(document).ready(function() {
        $("form").submit(function() {
            $(this).submit(function() {
                return false;
            });
            return true;
        });     
    }); 
</script>
มันจะทำงานได้อย่างแน่นอน
อนุญาตให้ส่งทุก 2 วินาที ในกรณีของการตรวจสอบความถูกต้องด้านหน้า
$(document).ready(function() {
    $('form[debounce]').submit(function(e) {
        const submiting = !!$(this).data('submiting');
        if(!submiting) {
            $(this).data('submiting', true);
            setTimeout(() => {
                $(this).data('submiting', false);
            }, 2000);
            return true;
        }
        e.preventDefault();
        return false;
    });
})
วิธีที่ดีที่สุดในการป้องกันการส่งหลายรายการคือเพียงแค่ส่งรหัสปุ่มในวิธีการ
    function DisableButton() {
        document.getElementById("btnPostJob").disabled = true;
    }
    window.onbeforeunload = DisableButton; 
การทำเช่นนี้โดยใช้จาวาสคริปต์นั้นค่อนข้างง่าย ต่อไปนี้เป็นรหัสที่จะให้ฟังก์ชันที่ต้องการ:
$('#disable').on('click', function(){
    $('#disable').attr("disabled", true);
  });<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="disable">Disable Me!</button>วิธีนี้ใช้ได้ดีมากสำหรับฉัน ส่งฟาร์มและทำให้ปุ่มปิดใช้งานและหลังจาก 2 วินาทีเปิดใช้งานปุ่ม
<button id="submit" type="submit" onclick="submitLimit()">Yes</button>
function submitLimit() {
var btn = document.getElementById('submit')
setTimeout(function() {
    btn.setAttribute('disabled', 'disabled');
}, 1);
setTimeout(function() {
    btn.removeAttribute('disabled');
}, 2000);}
ใน ECMA6 Syntex
function submitLimit() {
submitBtn = document.getElementById('submit');
setTimeout(() => { submitBtn.setAttribute('disabled', 'disabled') }, 1);
setTimeout(() => { submitBtn.removeAttribute('disabled') }, 4000);}
เพียงเพื่อเพิ่มคำตอบที่เป็นไปได้โดยไม่ผ่านการตรวจสอบการป้อนข้อมูลของเบราว์เซอร์
$( document ).ready(function() {
    $('.btn-submit').on('click', function() {
        if(this.form.checkValidity()) {
            $(this).attr("disabled", "disabled");
            $(this).val("Submitting...");
            this.form.submit();
        }
    });
});
อีกทางเลือกหนึ่งสำหรับสิ่งที่เสนอก่อนหน้านี้คือ:
jQuery('form').submit(function(){
     $(this).find(':submit').attr( 'disabled','disabled' );
     //the rest of your code
});