2009-01-14 19 views
16

को रोकना मैंने किसी ईवेंट के लिए साइन अप करने के लिए थोड़ा ऐप बनाया है। उपयोगकर्ता अपना डेटा इनपुट करते हैं और "मुझे साइन इन करें" पर क्लिक करें।डबल HTTP पोस्ट

अब कभी-कभी डेटाबेस में डबल होते हैं, वही डेटा जो एक-दूसरे के बाद 2 बार बहुत जल्दी डाला जाता है। इसका मतलब यह हो सकता है कि किसी ने बटन को दो बार क्लिक किया, जिससे दो पदों का कारण बन गया।

यह सामान्य वेब समस्या है, क्योंकि क्रेडिट कार्ड ऐप्स और फ़ोरम ऐप्स अक्सर कहते हैं: "एक बार क्लिक करना पर्याप्त है!"।

मुझे लगता है कि आप यह देखने के लिए सटीक उसी डेटा की जांच करके इसे हल कर सकते हैं कि पोस्ट अद्वितीय है या नहीं, लेकिन मुझे आश्चर्य है कि अन्य विधियां हैं या नहीं।

यह संभोग एएसपी.NET वेबफॉर्म के लिए नहीं गिना जाता है, क्योंकि POST उतना ही कोई फर्क नहीं पड़ता।

+0

[en.wikipedia.org/wiki/Post/Redirect/Get ](http://en.wikipedia.org/wiki/Post/Redirect/Get) –

उत्तर

21

जबकि जावास्क्रिप्ट समाधान क्लिक किए जाने के बाद सबमिट बटन को अक्षम कर सकते हैं, इसका उन लोगों पर कोई प्रभाव नहीं पड़ेगा जिनके पास जावास्क्रिप्ट अक्षम है।इसे हमेशा जोड़ने से पहले जावास्क्रिप्ट के बिना चीजों को सही ढंग से काम करना चाहिए, अन्यथा कोई बात नहीं है क्योंकि उपयोगकर्ता अभी भी जावास्क्रिप्ट को अक्षम करके चेक को बाईपास करने में सक्षम होंगे।

यदि वह पृष्ठ जहां प्रपत्र प्रकट होता है गतिशील रूप से जेनरेट किया गया है, तो आप एक छिपे हुए फ़ील्ड को जोड़ सकते हैं जिसमें कुछ प्रकार के अनुक्रम संख्या, एक हैश या कुछ अद्वितीय हो। फिर आपके पास कुछ सर्वर-साइड सत्यापन है जो जांच करेगा कि उस अद्वितीय मान के साथ अनुरोध पहले ही आ चुका है। जब उपयोगकर्ता फॉर्म सबमिट करता है, तो अद्वितीय मान "प्रयुक्त" मानों की सूची के विरुद्ध चेक किया जाता है। यदि यह सूची में मौजूद है, तो यह एक डुप्लिकेट अनुरोध है और इसे त्याग दिया जा सकता है। यदि यह अस्तित्व में नहीं है, तो इसे सामान्य रूप से सूची और प्रक्रिया में जोड़ें। जब तक आप सुनिश्चित करते हैं कि मान अद्वितीय है, तो यह गारंटी देता है कि उसी फॉर्म को दो बार सबमिट नहीं किया जा सकता है।

बेशक, यदि फॉर्म चालू है, तो गतिशील रूप से जेनरेट नहीं किया गया है, तो आपको यह जांचने के लिए सर्वर-साइड पर कठिन तरीका करना होगा कि वही जानकारी पहले ही सबमिट नहीं की गई है।

+2

समस्या का आपका समाधान ठीक है। लेकिन एक छुपा क्षेत्र क्लाइंट द्वारा देखा जा सकता है और उसे हमारे आवेदन को खराब करने के लिए संपादित किया जा सकता है जो दोबारा फॉर्म फिर से स्वीकार कर सकता है। मैं एक ऐसे समाधान की तलाश में हूं जो पूरी तरह से सर्वर के लिए उन्मुख है। –

+0

यदि आपके पास कुछ लोड बैलेंसर है, तो सर्वर को स्टोर करने और पढ़ने के लिए सर्वर पर एक यूयूआईडी (या किसी भी प्रकार का अद्वितीय नंबर) भेजें, यदि सर्वर अन्य सर्वरों के बारे में अवगत नहीं है, तो प्रत्येक अनुरोध को अलग-अलग द्वारा संसाधित किया जा सकता है सर्वर। – Dherik

4

उपयोगकर्ता-पक्ष समाधान पहली क्लिक के बाद जावास्क्रिप्ट के माध्यम से सबमिशन बटन को अक्षम करना है।

इसमें कमी है, लेकिन मुझे लगता है कि यह अक्सर ई-कॉमर्स वेबसाइटों पर उपयोग किया जाता है।

लेकिन, यह वास्तविक सर्वर-साइड सत्यापन को कभी भी प्रतिस्थापित नहीं करेगा।

+0

यह सर्वर-साइड डिटेक्शन के लिए एक उपयोगी जोड़ हो सकता है, क्योंकि यह आपके दूसरे क्लिक को "आप डबल-पोस्ट, बेवकूफ" पृष्ठ पर ले जा सकता है। जल्द ही बाद में बटन को फिर से सक्षम करना एक अच्छा विचार है ताकि आकस्मिक डबल-क्लिक को जानबूझकर दूसरे उपयोग के लिए फ़ॉर्म को तोड़ने के बिना रोका जा सके। – bobince

0

क्लाइंट साइड परिवर्तन एक आम तकनीक है:

  • अक्षम सबमिट बटन
  • बदलें करने के लिए स्क्रीन के लिए एक "कृपया प्रतीक्षा करें" स्क्रीन
  • तो प्रपत्र मोडल था, स्क्रीन अपने सामान्य करने के लिए वापस बदल रहा है प्रक्रिया (यह चीजों को वास्तव में चिकना दिखने का लाभ है)

लेकिन यह सही नहीं है। यह सब जेएस पर उपलब्ध है और यदि यह मामला नहीं है, बैक-एंड डुप्लिकेशंस डिटेक्शन के बिना, आपको अभी भी डुप्लिकेट मिलेंगे।

तो मेरी सलाह है कि दृश्यों के पीछे कुछ प्रकार का पता लगाना और फिर जेएस के साथ लोगों को डबल-सबमिट करने में सक्षम होने के लिए अपने फॉर्म में सुधार करें।

0

आप फ़ॉर्म को सबमिट किए जाने की संख्या को ट्रैक कर सकते हैं और सत्र में उस फ़ॉर्म के साथ पृष्ठ पर अनन्य विज़िट की संख्या से इसकी तुलना कर सकते हैं।

17

अब तक के अधिकांश उत्तर क्लाइंट-साइड रहे हैं। सर्वर-साइड पर, जब आप पहली बार फॉर्म का उत्पादन करते हैं, तो आप एक GUID के साथ एक छिपे हुए फ़ील्ड को उत्पन्न कर सकते हैं, और तब पोस्ट प्राप्त होने पर उस GUID को सबमिट किए गए फॉर्म के रूप में रिकॉर्ड करें। कोई और प्रसंस्करण करने से पहले इसे जांचें।

+0

+1 क्लाइंट साइड पर्याप्त विश्वसनीय नहीं है जहां डेटा भ्रष्टाचार एक संभावना है, खासकर जहां एक बार की कुंजी विधि बहुत अच्छी तरह से काम करती है – annakata

+2

(असल में, बस जोड़ना चाहता था कि मैं व्यक्तिगत रूप से क्वेरीस्ट्रिंग पर उस कुंजी को रखना पसंद करता हूं छुपा हुआ क्षेत्र) – annakata

3

क्लाइंट साइड तकनीक उपयोगी हैं, लेकिन आप इसे कुछ सर्वर साइड तकनीकों के साथ जोड़ना चाह सकते हैं।

ऐसा करने का एक तरीका है फॉर्म में एक अद्वितीय टोकन (उदाहरण के लिए GUID या इसी तरह), ताकि जब आप फॉर्म को संसाधित करने के लिए आते हैं तो आप यह देखने के लिए जांच सकते हैं कि टोकन का उपयोग पहले से ही किया जा रहा है या नहीं, डबल सबमिशन।

आपके मामले में, यदि आपके पास ईवेंट विज़िटर के साथ एक टेबल है, तो आप इस टोकन को कॉलम के रूप में शामिल कर सकते हैं।

0

पहले से उल्लिखित कई अच्छी तकनीकों के अलावा, एक और सरल सर्वर-साइड विधि, जिसमें सत्र की आवश्यकता है, में एक सत्र चर होना है जो पहले सबमिट पर बंद हो जाता है।

3

क्लाइंट-केवल समाधान पर्याप्त नहीं होगा, जैसा कि यहां कई उत्तरों में बताया गया है। आपको सर्वर-साइड असफल-सुरक्षित के साथ जाना होगा।

सबमिट बटन को अक्षम करने का अक्सर अनदेखा कारण यह नहीं है कि उपयोगकर्ता बस सबमिट लक्ष्य को रीफ्रेश कर सकता है (और "क्या आप वाकई POST डेटा पुनः सबमिट करना चाहते हैं?" संवाद पर ठीक क्लिक करें)। या यहां तक ​​कि, जब आप पृष्ठ को डिस्क पर सहेजने का प्रयास करते हैं, तो कुछ ब्राउज़र सबमिट किए गए पृष्ठ को फिर से लोड कर सकते हैं (उदाहरण के लिए, आप ऑर्डर पुष्टिकरण की हार्ड-कॉपी सहेजने की कोशिश कर रहे हैं)।

+0

मैं इसके बारे में सोच रहा था, हम अकेले केवल जावास्क्रिप्ट के साथ डबल सबमिशन को रोक नहीं सकते हैं। – cherit

1

लगभग किसी के पास जेएस अक्षम नहीं है। 70 साल की महिला के लिए अपनी ई-कॉमर्स वेबसाइट को कोड करने के बारे में सोचें जो प्रत्येक लिंक और बटन पर डबल क्लिक करता है। आप बस इतना करना चाहते हैं कि उसे दोबारा "ऑर्डर नाउ" पर क्लिक करने से रोकने के लिए जावास्क्रिप्ट जोड़ें। हां - सर्वर पक्ष पर भी यह जांचें "रक्षात्मक रहें" - लेकिन उस मामले के लिए कोड न करें। लेकिन बेहतर यूआई के लिए यह क्लाइंट साइड पर भी करता है।

// 
// prevent double-click on submit 
// 
    jQuery('input[type=submit]').click(function(){ 
    if(jQuery.data(this, 'clicked')){ 
     return false; 
    } 
    else{ 
     jQuery.data(this, 'clicked', true); 
     return true; 
    } 
    }); 

और

// Find ALL <form> tags on your page 
$('form').submit(function(){ 
    // On submit disable its submit button 
    $('input[type=submit]', this).attr('disabled', 'disabled'); 
}); 
2

जब भी कोई पेज सर्वर से अनुरोध किया जाता है, एक अद्वितीय requestToken उत्पन्न, सर्वर साइड में सहेजने, के रूप में मार्क की स्थिति:

यहाँ कुछ स्क्रिप्ट है कि मैं पाए जाते हैं संसाधित नहीं किया गया है और वर्तमान अनुरोधित पृष्ठ के साथ इसे पास कर दिया है। अब जब भी कोई पृष्ठ सबमिट होता है, अनुरोध प्राप्त करें "POST" एड डेटा से टोकन प्राप्त करें और स्थिति की जांच करें और डेटा को सहेजें या वैकल्पिक कार्रवाई करें।

अधिकांश बैंकिंग अनुप्रयोग डबल "पोस्ट" आईएनजी को रोकने के लिए इस तकनीक का उपयोग करते हैं। इसलिए यह एक समय साबित हुआ है कि & डबल सबमिशन को रोकने का विश्वसनीय तरीका है।

+0

चेरिट, आइए मान लें कि क्लाइंट को टोकन मिला है और वह एक पोस्ट सबमिट करता है। POST ने इसे सर्वर पर बनाया लेकिन जवाब पर वापस, नेटवर्क प्रभावित हो गया। उपयोगकर्ता को कोई प्रतिक्रिया नहीं मिली। वह फॉर्म पेज को रीफ्रेश करता है। क्या उसे पहले पोस्ट के बाद से एक नया टोकन मिलना चाहिए? – devwannabe

+1

@devwannabe जब उपयोगकर्ता पृष्ठ को रीफ्रेश करता है, ब्राउज़र फॉर्म डेटा को सौजन्य के रूप में पुनः भेजने के लिए कहेंगे। ब्राउज़र एक ही फॉर्म डेटा भेज सकता है, लेकिन सर्वर समाप्त हो चुके टोकन के आधार पर इसे अस्वीकार कर सकता है। यदि सर्वर को समाप्त हो चुके टोकन की जांच करने के लिए कोड नहीं किया गया है, तो इसके परिणामस्वरूप उसी डेटा को डबल सबमिट किया जा सकता है। समाप्त हो चुके टोकन को संभालने का तरीका एक सर्वर के पक्ष को किसी अन्य पृष्ठ पर रीडायरेक्ट करना है कि 'आपका डेटा पहले ही सबमिट हो चुका है' या यदि यह अजाक्स कॉल है, तो तदनुसार एक त्रुटि प्रतिक्रिया। इसका अनौपचारिक रूप से पीआरजी पैटर्न कहा जाता है। अधिक -> http://www.theserverside.com/news/1365146/Redirect-After-Post – cherit

+0

इसका मतलब है कि ब्राउज़र उसी डेटा को फिर से भेजना ठीक है जब तक बैकएंड जानता है कि डेटा को कैसे सत्यापित किया जाए। बैकएंड को हमेशा सत्यापित करना होगा यदि अनुरोध पहले ही पूरा हो चुका है और यदि ऐसा है, तो उपयोगकर्ता को दूसरे पृष्ठ पर रीडायरेक्ट करें। – devwannabe

1

कोई भी समाधान लोड-बैलेंस सर्वर को संबोधित नहीं करता है।

यदि आपके पास कुछ लोड बैलेंसर है, तो सर्वर को स्टोर करने और पढ़ने के लिए सर्वर पर एक यूयूआईडी (या किसी भी प्रकार का अद्वितीय नंबर) भेजें, यदि सर्वर अन्य सर्वरों के बारे में अवगत नहीं है, तो प्रत्येक अनुरोध को संसाधित किया जा सकता है एक स्टेटलेस वातावरण में एक अलग सर्वर द्वारा। इन सर्वरों को एक ही स्थान पर पढ़ने/लिखने की आवश्यकता है।

आप कई सर्वरों आप सर्वर को पढ़ने के लिए के बीच में कुछ साझा कैश (एक Redis की तरह) की आवश्यकता होगी है/एक ही स्थान पर अनूठा मूल्य लिखना (क्या इंजीनियरिंग समाधान पर एक हो सकता है, लेकिन काम करता है)।

संबंधित मुद्दे