여러 양식 제출 방지 (서버 측)


9

사용자가 Form API로 작성된 모든 양식을 여러 번 제출할 수있는 문제가 발생합니다 (빠른 클릭으로 여러 요청이 발생 함).

버튼을 비활성화하는 기본 클라이언트 측 (자바 스크립트) 솔루션에 넣었지만이 상황을 방지하는 가장 좋은 방법이 서버 측에 있는지 궁금합니다.

Drupal의 폼 토큰 시스템을 사용하여이를 처리하는 권장 방법이 있습니까? 특히 전역 양식 솔루션 (즉, hook_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']를 사용하기 시작했습니다. 동일한 양식 빌드 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. 모듈 가중치 음수 maximum_value (-2000 일 수 있음)를 가져야하는 하나의 모듈 (first_module)은 다음 코드를 사용하여 hook_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. 모듈에 제출 콜백을 추가하여 세션을 설정 해제해야합니다.

함수 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

코딩없이 모든 양식에 대해이 기능을 사용하고 더 많은 제어 기능을 원하면 숨기기 단추 숨기기 모듈을 살펴보십시오 .

풍모:

  1. 제출 버튼을 클릭 한 후 숨기기 또는 비활성화
  2. 기다리는 동안 메시지 및 / 또는 이미지 표시

5
Submt Button 숨기기 모듈은 서버 측 솔루션이 아닙니다. 모듈 설명에서 : "Javascript가 비활성화 된 브라우저의 경우이 모듈은 전혀 영향을 미치지 않습니다." drupal.org/project/hide_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);',
  ),
);

이것이 도움이 되길 바랍니다 ..

또는 제출 버튼의 여러 클릭 방지 및 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();
    });
  }
});
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.