10

ठीक है, सबकुछ शीर्षक में है लेकिन मैं थोड़ा और समझाऊंगा :-)रेल नियंत्रकों में, डबल सबमिट को रोकने के लिए कैसे करें (जब उपयोगकर्ता डबल-क्लिक सबमिट बटन या दो बार दर्ज करें)?

मेरे रेल ऐप में कई रूप हैं (अजाक्सिफाइड या नहीं)।

उपयोगकर्ताओं को दो या दो से अधिक फॉर्म सबमिट करने से रोकने के लिए, मैं जावास्क्रिप्ट का उपयोग करता हूं।

एक Ajaxified फार्म के लिए मेरी परिदृश्य नहीं है:

  • जावास्क्रिप्ट को अक्षम सबमिट बटन

    • उपयोगकर्ता फ़ॉर्म सबमिट (CLIC या प्रवेश)
    • रेल नियंत्रक बातें (एक साबुन अनुरोध पसंद करते हैं या एक DB में एक डालने)
    • रेल नियंत्रक अद्यतन पेज और त्रुटि के मामले में सबमिट बटन यदि आवश्यक हो तो()
    सक्षम

    अब यदि उपयोगकर्ता जावास्क्रिप्ट को बाईपास करता है तो चीजों को वास्तव में साफ रखने के लिए मैं सर्वर साइड कोड जोड़ना चाहता हूं।

    कोई सुझाव?

  • उत्तर

    5

    Redis ताला उपयोग करने का प्रयास और तरह

    Redis.current.lock("#{current_user.id}.action_name") do 
        # Some code 
    end 
    

    यह मणि मैं https://github.com/mlanett/redis-lock

    +1

    अरे, यह एक पुरानी पोस्ट है लेकिन वैसे भी जवाब के लिए धन्यवाद। मुझे वास्तव में रेडिस लॉकिंग के साथ इस दृष्टिकोण को पसंद है। –

    1

    कोई असली सुझाव नहीं है (मैं डाउनवॉट्स से आश्चर्यचकित नहीं होगा), लेकिन क्या आपकी साइट अभी भी जेएस के बिना उपयोग योग्य होगी? उसे उचित संदेश दिखाने के बारे में कि सामान्य ऑपरेशन के लिए उसे जेएस को सक्षम करने की आवश्यकता है, अन्यथा आप उसे पृष्ठ पर बहुत सारे और बहुत सारे फॉर्म नहीं दिखाएंगे।

    +0

    सच है और आपने मुझे अपना प्रश्न संपादित किया है :-) उपयोगकर्ता का मामला मैं बात कर रहा हूं जब उपयोगकर्ता जावास्क्रिप्ट को बाईपास करता है। जावास्क्रिप्ट हमेशा सक्रिय है पर विचार करें। मेरा सवाल ज्यादातर सर्वर-साइड भाग के बारे में है .. –

    0

    1) कुछ चलने वाले संकेतक को यह भी अच्छा लगता है कि उपयोगकर्ता को यह पता चल जाए कि कुछ चल रहा है, कि उनके अनुरोध पर संसाधित किया जा रहा है। इसे बहुत से डबल सबमिशन को खत्म करना चाहिए।

    2) यदि उपयोगकर्ता ने जावास्क्रिप्ट को अक्षम कर दिया है, तो आप 'AJAXified' फ़ॉर्म कैसे सबमिट करेंगे? यदि साइट जावास्क्रिप्ट के बिना कार्यात्मक नहीं हो पाती है, तो शायद उपयोगकर्ता को सूचित करने के लिए सबसे अच्छा है (जैसे ईमैंटास सुझाता है)।

    संपादित इस तरह के सूचक का एक उदाहरण है, मैं क्या होता है बस स्पष्ट मैं में 1.
    http://www.netzgesta.de/busy/

    +0

    1) निश्चित रूप से, मैं एक 2 लागू करूंगा 2) मैंने अपना प्रश्न संपादित कर लिया है: असली समस्या यह है कि उपयोगकर्ता जावास्क्रिप्ट को बाईपास करता है। (यदि उपयोगकर्ता जावास्क्रिप्ट को अक्षम करता है, तो फ़ॉर्म सबमिट करने की प्रक्रिया सामान्य रूप से संसाधित की जाती है .. डबल सबमिट को रोकने की कोई आवश्यकता नहीं है) –

    2

    यहाँ क्या मतलब हो:

    1. एक "टोकन" फ़ील्ड जोड़ें डीबी में एक ऑब्जेक्ट के लिए जो बदला जा रहा है।
    2. उस टोकन को उस फ़ॉर्म में रखें जो ऑब्जेक्ट को संशोधित करता है।
    3. संशोधन के ठीक बाद उस ऑब्जेक्ट को नए टोकन से बचाएं।
    4. अन्य पृष्ठ दृश्यों में उस टोकन का उपयोग करें।

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

    यह भी नव निर्मित वस्तुओं के लिए आकर्षित है (यानी यदि उपयोगकर्ता कोई टिप्पणी बनाना चाहता है या उस तरह smth)।लेकिन इस मामले में आप उसी उपयोगकर्ता से निर्माण समय अंतराल की जांच कर सकते हैं और यदि यह 5 सेकंड से कम है, तो आप ऑब्जेक्ट को "बनाए गए" होने से रोक देंगे।

    +0

    हाँ, यह एकाधिक प्रविष्टियों को संभालने का भी एक अच्छा तरीका है। –

    +0

    टैगिंग अनुरोधों का यह दृष्टिकोण आरएमआई/आरपीसी में टैगिंग संदेशों के समान है, जो अनिवार्य रूप से वही बात है। प्रति मॉडल या ऑब्जेक्ट जैसे फाइनर-अनाज पर टैग करना भी संभव है, और यह देखें कि नियंत्रक डुप्लिकेट पर कैसे प्रतिक्रिया करता है (उदाहरण के लिए डेटाबेस ऑपरेशन छोड़ें लेकिन फिर भी नया पृष्ठ दिखाएं - उपयोगकर्ता को पता नहीं है कुछ गलत हो गया)। – nruth

    0

    सुनिश्चित नहीं हैं कि अगर यह उपयोगी है:

    serverside पर:

    1. फार्म की ताजा लोड होने पर, एक सत्र सेट [ 'चर'] झूठी = // प्रपत्र 'isn अर्थ टी अभी तक सबमिट नहीं किया।

    2. प्रपत्र पर प्रस्तुत की जाँच करें,: "... कृपया प्रतीक्षा करें" disable_with => प्रस्तुत टैग करने के लिए:

      if session['variable'] == true 
      { 
          do nothing... 
      } 
      else 
      { 
          set session['variable'] = true; 
          //do submit logic here 
      } 
      
    +0

    यह दोबारा सबमिट करने से कैसे रोकता है?यदि कोई उपयोगकर्ता दो बार जल्दी सबमिट बटन क्लिक करता है (इसलिए पहला अनुरोध अभी तक बैक-एंड तक नहीं पहुंच पाया है), दूसरा सबमिट अभी भी सत्र ['variable'] = false होगा। –

    7

    आप विकल्प को जोड़ सकते हैं।

    +0

    ग्राहक पक्ष सुविधा, जो मैं खोज रहा था नहीं। वैसे भी Thx, टिप अन्य मामलों में उपयोगी है। –

    +1

    सावधान। इसके साथ एकल सबमिट को रोकने के लिए असंभव नहीं है। अभी भी सुनिश्चित नहीं है कि कुछ उपयोगकर्ताओं के लिए इस त्रुटि को किसने ट्रिगर किया, केवल कुछ ही किया। – Ricky

    +0

    मेरा मानना ​​है कि यह रेल 4 में बहिष्कृत है: http://stackoverflow.com/a/9572893/1945948। –

    6

    उपयोग कर रहा हूँ मैं 4 4 के लिए विधि परिदृश्यों का उपयोग है कुछ के साथ अपने ब्लॉक के चारों ओर, सबसे पहले मेरी awnser यहाँ पसंद करते कृपया : Prevent double submits in a Rails AJAX form

    केवल उन के लिए सीमा पर क्लिक करें:

    उपयोग stopImmedia teprropagation और लक्ष्य डोम पर एक क्लिक घटना जोड़ें।

    /** 
        * 防止按钮重复点击。 
        * NOTICE: #1 需要在作用点之前调用此方法 #2 stopImmediatePropagation 会阻止后面的所有事件包括事件冒泡 
        * @delay_duration 两次点击的间隔时间 
        */ 
        $.fn.preventMultipleClick = function (delay_duration) { 
        delay_duration = delay_duration || 3000; 
        var last_click_time_stamp = 0; 
        var time_duration = 0; 
        $(this).bind('click', function (event) { 
         time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0; 
         //console.debug("preventMultipleClick", last_click_time_stamp, time_duration); 
         if (time_duration && time_duration < delay_duration) { 
         event.stopImmediatePropagation(); 
         } else { 
         //console.debug("skip preventMultipleClick~"); 
         last_click_time_stamp = event.timeStamp; 
         } 
        }); 
        }; 
    

    सीमा ऐसे ajax के रूप में प्रस्तुत:

    उपयोग ajax के beforeSend attribut।

    <%= f.submit "Save annotation", :disable_with => "Saving...", :class => "btn btn-primary", :id => "annotation-submit-button" %> 
    

    या: अक्षम:

    /** 
        * 使用: 
        * 在jquery的ajax方法中加入参数:beforeSend 
        * 例如:beforeSend: function(){return $.preventMultipleAjax(event, 5000)} 
        * 
        * @param event 
        * @param delay_duration 
        * @returns {boolean} 
        */ 
        $.preventMultipleAjax = function (event, delay_duration) { 
        delay_duration = delay_duration || 3000; 
        var target = $(event.target); 
        var last_click_time_stamp = target.attr("_ajax_send_time_stamp") || 0; 
        var time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0; 
        //console.debug("preventMultipleAjax", last_click_time_stamp, time_duration); 
        if (time_duration && time_duration < delay_duration) { 
         return false; 
        } else { 
         //console.debug("skip preventMultipleAjax~"); 
         target.attr("_ajax_send_time_stamp", event.timeStamp); 
         return true; 
        } 
        }; 
    
    केवल फार्म के लिए

    仅仅 对 表单 元素, 按钮 等 起作用, 会 阻止 其 上 的 事件 触发

    <input type="submit" value="submit" /> 
    <input type="button" value="button" /> 
    <input type="image" value="image" /> 
    

    दूसरों:

    यह मणि है: https://github.com/mlanett/redis-lock

    Redis.current.lock("#{current_user.id}.action_name") do 
        # Some code 
    end 
    
    +0

    विभिन्न समाधान क्लाइंट और सर्वर पक्ष का अच्छा सारांश। शायद चीनी भागों का अनुवाद किया जा सकता है। :-) –

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