บางครั้งเมื่อการตอบกลับช้าอาจมีการคลิกปุ่มส่งหลายครั้ง
จะป้องกันไม่ให้เกิดขึ้นได้อย่างไร?
บางครั้งเมื่อการตอบกลับช้าอาจมีการคลิกปุ่มส่งหลายครั้ง
จะป้องกันไม่ให้เกิดขึ้นได้อย่างไร?
คำตอบ:
ใช้จาวาสคริปต์ที่ไม่สร้างความรำคาญเพื่อปิดใช้งานการส่งเหตุการณ์ในแบบฟอร์มหลังจากที่ส่งไปแล้ว นี่คือตัวอย่างการใช้ 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
});