Запобігання надсилання декількох форм (сторона сервера)


9

У мене виникає проблема, коли користувач може надсилати будь-яку форму, побудовану API API декілька разів (швидке клацання призводить до декількох запитів).

Я вклав у базове рішення клієнта (javascript) відключення кнопки, але мені цікаво, який найкращий підхід до запобігання цій ситуації є на стороні сервера.

Чи є рекомендований спосіб використовувати систему токенів форми Drupal для цього? Особливо глобальне рішення форми (тобто додавання користувацького валідатора до кожної форми за допомогою гачок_form_alter ()).

Мій підхід до цього часу був приблизно таким:

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;
  }
}

У мене виникають проблеми, коли form_token не є унікальним для форми - він, здається, залишається таким же, незалежно від того, що станеться. Я, мабуть, не розумію, що лексема є у грандіозній схемі форми api.

Будь-яке розуміння цінується!


У подальшому я почав використовувати $ form_state ['form_build_id'] замість маркера. Якщо я надсилаю один і той же ідентифікатор збірки форми двічі, десь по дорозі форму буде відновлено та оброблено в будь-якому випадку.
PrairieHippo

Відповіді:


8

У мене була точно така ж проблема і мені вдалося її виправити за допомогою механізмів блокування від Drupal

У функції перевірки я використав:

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."));
  }
}

І у функції подання я випустив замок:

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

1

Тут слід врахувати вагу модуля:

  1. Один модуль (нехай first_module), який повинен мати негативну максимум значення ваги модуля (може бути -2000), тут він повинен реалізувати гачку_form_alter () із наступним кодом. Тепер ви повинні перевірити, чи форма вже подана вашим кодом чи ні.
   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. Другий_модуль, який має вагу позитивного більш високого значення. Ось вам слід зняти сеанс, додавши зворотній виклик надіслати в модуль

функція 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

Якщо ви хочете, щоб ця функціональність була в усіх формах і більше контролю без кодування, подивіться на модуль Hide Submit Button .

Особливості:

  1. Сховати або вимкнути кнопку для надсилання після її натискання
  2. Відображення повідомлення та / або зображення під час очікування

5
Модуль кнопки Hide Submt не є рішенням на стороні сервера. З опису модуля: "Для браузерів з відключеним Javascript цей модуль взагалі не матиме ефекту." drupal.org/project/hide_submit
Блейк Фредерік

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);',
  ),
);

сподіваюся, що це допоможе ..

або ви можете посилатися Попередження декількох клацань кнопки подання & drupal має один модуль Сховати кнопку подання

Деякі користувачі випадково натискають кнопку "Надіслати" кілька разів, очікуючи збереження їх публікації. У деяких випадках це може призвести до повторних публікацій або копій замовлень електронної комерції.


-1

Це було моєю проблемою і раніше. Моє рішення для цього - відключити кнопку через JS.

.модуль:

/**
 * 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();
    });
  }
});
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.