Ngăn chặn nhiều lần gửi (phía máy chủ)


9

Tôi đang gặp vấn đề trong đó người dùng có thể gửi bất kỳ biểu mẫu nào được API Mẫu tạo ra nhiều lần (nhấp nhanh dẫn đến nhiều yêu cầu).

Tôi đã đưa vào giải pháp vô hiệu hóa phía máy khách cơ bản (javascript), nhưng tôi tò mò không biết cách tiếp cận tốt nhất để ngăn chặn tình huống này là ở phía máy chủ.

Có cách nào được đề xuất để sử dụng hệ thống mã thông báo biểu mẫu của Drupal để xử lý việc này không? Đặc biệt là một giải pháp biểu mẫu toàn cầu (nghĩa là thêm trình xác nhận tùy chỉnh vào mọi biểu mẫu bằng hook_form_alter ()).

Cách tiếp cận của tôi cho đến nay là một cái gì đó như thế này:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['#validate'][] = 'mymodule_form_validate';
}

function mymodule_form_validate(&$form, &$form_state){
  //initialize form array
  if (!isset($_SESSION['submitted_forms'])){
    $_SESSION['submitted_forms'] = array();
  }

  $form_token = $form_state['values']['form_token'];
  if ( isset($_SESSION['submitted_forms'][$form_token]) && $_SESSION['submitted_forms'][$form_token] = TRUE ){
    form_set_error('name]', 'This form has already been submitted');
  }
  else{
    $_SESSION['submitted_forms'][$form_token] = TRUE;
  }
}

Tôi đang gặp rắc rối khi form_token không phải là duy nhất cho biểu mẫu - nó dường như giữ nguyên cho dù điều gì xảy ra. Tôi có thể hiểu nhầm mã thông báo là gì trong sơ đồ lớn của mẫu api.

Bất kỳ cái nhìn sâu sắc được đánh giá cao!


Để theo dõi, tôi bắt đầu sử dụng $ form_state ['form_build_id'] thay vì mã thông báo. Nếu tôi gửi cùng một id xây dựng biểu mẫu hai lần, ở đâu đó trên đường đi, biểu mẫu sẽ được xây dựng lại và xử lý mọi cách.
PrairieHippo

Câu trả lời:


8

Tôi đã có cùng một vấn đề chính xác và đã cố gắng khắc phục bằng cách sử dụng các cơ chế Khóa từ Drupal

Trong hàm xác thực tôi đã sử dụng:

function mymodule_custom_form_validate($form, &$form_state){
  if (lock_acquire('your_custom_lock_name')) {
    // long operations here
  } else {
    form_set_error("", t("You submitted this form already."));
  }
}

Và trong chức năng gửi tôi đã phát hành khóa:

function mymodule_custom_form_submit($form, &$form_state){
  // submit code
  lock_release('your_custom_lock_name');
}

1

Ở đây bạn nên xem xét trọng lượng mô-đun:

  1. Một mô-đun (hãy để First_module) có trọng số mô-đun âm Maximum_value (có thể là -2000) ở đây, nó sẽ triển khai hook_form_alter () với mã sau đây. Bây giờ bạn nên xác minh xem biểu mẫu đã được gửi hay chưa bởi mã của bạn.
   function first_module_form_alter(&$form, &$form_state, $form_id)
    {
      $form['#validate'][] = 'mymodule_form_validate';
    }
function mymodule_form_validate(&$form, &$form_state){
  //a($form_state);
  //initialize form array
  if (!isset($_SESSION['submitted_forms'])){
    $_SESSION['submitted_forms'] = array();
  }

  $form_token = $form_state['values']['form_id'];
  if ( isset($_SESSION['submitted_forms'][$form_token]) && $_SESSION['submitted_forms'][$form_token] = TRUE ){
    form_set_error('name]', 'This form has already been submitted');
  }
  else{
    $_SESSION['submitted_forms'][$form_token] = TRUE;
  }
}
  1. Thứ hai_module có trọng số của giá trị cao hơn sở hữu. Bạn nên bỏ đặt phiên bằng cách thêm cuộc gọi lại gửi đến một mô-đun

hàm second_module_form_alter (& $ form, & $ form_state, $ form_id) {$ form ['# submit'] [] = 'mymodule_form_submit'; }

function mymodule_form_submit(&$form, &$form_state){

  $form_token = $form_state['values']['form_id'];
  unset($_SESSION['submitted_forms'][$form_token]);

}

1

Nếu bạn muốn chức năng này trên tất cả các biểu mẫu và kiểm soát nhiều hơn mà không cần mã hóa, hãy xem mô-đun Ẩn nút gửi .

Đặc trưng:

  1. Ẩn hoặc tắt nút gửi sau khi đã nhấp vào
  2. Hiển thị tin nhắn và / hoặc hình ảnh trong khi chờ đợi

5
Mô-đun Hide Submt Nút không phải là giải pháp phía máy chủ. Từ mô tả của mô-đun: "Đối với các trình duyệt bị tắt Javascript, mô-đun này sẽ không có hiệu lực nào cả." drupal.org/project/ leather_submit
Blake Frederick

0
$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('Save'),
  '#attributes' => array(
    'onclick' => 'javascript:var s=this;setTimeout(function(){s.value="Saving...";s.disabled=true;},1);',
  ),
);

hy vọng điều này sẽ giúp ..

hoặc bạn có thể tham khảo Ngăn chặn nhiều lần nhấp vào nút gửi & drupal có một mô-đun Ẩn nút gửi

Một số người dùng vô tình nhấp vào nút gửi nhiều lần trong khi chờ bài đăng của họ được lưu. Trong một số trường hợp, điều này có thể dẫn đến các bài đăng trùng lặp hoặc các đơn đặt hàng thương mại điện tử trùng lặp.


-1

Đây cũng là vấn đề của tôi trước đây. Giải pháp của tôi cho vấn đề này là vô hiệu hóa nút thông qua JS.

.module:

/**
 * Implementation of hook_init().
 */
function myModule_init(){
if (arg(0) == 'node' && (arg(2) == 'edit' || arg(1) == 'add')) {
    //hide btn when clicked on article nodes
    drupal_add_js(drupal_get_path('module', myModule') . '/js/disable-submit.js');
}

JS:

Drupal.behaviors.module_disable_submit = function (context) {

/* 
 * Disable keypress on form fields.
 * Prevent browser to reload when pressing enter in input fields 
 */


$('.buttons input:submit').click(function() {
  $('.buttons input:submit').hide();
  $('#node-form .buttons').prepend('<input type="submit" style="margin:1px 0; box-shadow:0 1px 1px #DDDDDD; border-radius:3px 3px 3px 3px; background:url(/sites/all/themes/rubik/images/bleeds.png) repeat-x scroll 0 -41px #F4F4F4; border-color:#DDDDDD #DDDDDD #CCCCCC; border-style:solid; border-width:1px; color:#B8A98F; cursor:default; font-weight:normal; padding:2px 10px; text-align:center;" value="Saving..." name="op" onclick="return false;" />');
  if ('.buttons input:submit') {
    $('.buttons input:submit').keypress(function() {
      $('.buttons input:submit').parents("form").submit();
      $('.buttons input:submit').hide();
    });
  }
});
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.