Почему эта форма может быть отправлена? (Fire Fox)

У меня очень странная ошибка в Firefox (версия 38.05). У меня есть форма, которая выглядит следующим образом, и Javascript, вырезанный для проверки

<form action='#' onsubmit='return check()'>
    <input type='text' name='asdf'/>
    <input type='submit' name='jkl' value='Submit'/>
</form>

Javascript

function check(){
    alert("asdf");
    return false;
}

Теперь эта форма никогда не должна быть отправлена. Но в Firefox его можно отправить без отключения Javascript, если вы выполните следующую процедуру:

  1. Нажмите отправить
  2. Подтвердите диалоговое окно предупреждения
  3. Нажмите отправить еще раз
  4. Установите флажок, чтобы предотвратить дальнейшие окна предупреждений, и нажмите «ОК».
  5. Нажмите отправить --> форма будет отправлена

Это баг или фича? В Хроме все работает нормально. Если это поведение предназначено, как я могу его избежать?


person chillichief    schedule 30.06.2015    source источник
comment
это не баг это фича   -  person Magicprog.fr    schedule 30.06.2015
comment
Из-за наличия alert и его исторической дурацкости я полагаю, что это старый добрый баг. Фрагмент может помочь!   -  person Kyll    schedule 30.06.2015
comment
просто избегайте использования alert и используйте console.log   -  person Hacketo    schedule 30.06.2015
comment
console.log не вариант. Это должно быть сообщение для пользователя, который заполняет форму   -  person chillichief    schedule 30.06.2015
comment
@chillichief Я только что обновил свой ответ, чтобы помочь вам отобразить пользовательское предупреждение.   -  person Magicprog.fr    schedule 30.06.2015


Ответы (3)


Итак, что происходит, когда alert() вызывается, когда пользователь заблокирован, Firefox и Chrome ведут себя по-разному!

В то время как Chrome просто молча терпит неудачу, попытка alert в Firefox, когда он был заблокирован пользователем, вызывает исключение. А обработчики onSubmit блокируются только в том случае, если функция явно возвращает false.

Несколько грязным исправлением будет:

function check() {
  try {
    alert('foo');
  }
  catch {
    //User prevented alerts, fallback
    showSomehow('foo'); //use a log, a div on the top of the page, ...
  }
  return false;
}

Нужно иметь больше мотивации, чем я, и вникать в глубину спецификаций, чтобы знать, кто прав в этом.

person Kyll    schedule 30.06.2015
comment
как он сказал в комментариях console.log is not an option. This is supposed to be a message to the user who fills out the form – - person Magicprog.fr; 30.06.2015
comment
@Magicprog.fr Ну да, но когда alert больше нельзя делать, нужно прибегнуть к чему-то другому. Позвольте мне прояснить это. - person Kyll; 30.06.2015
comment
@Magicprog.fr, нет, вопрос в том, почему можно отправить эту форму, а не в том, как отображать предупреждение, когда пользователь заблокировал стандартную форму. - person Pavlo; 30.06.2015
comment
@Pavlo Ну, название такое, да, но как насчет If this behaviour is intended, how can i avoid it? - person Magicprog.fr; 30.06.2015
comment
Да будет ясно: если пользователь не хочет, чтобы его alerted, вы не сможете вызвать alert(). Конец линии. Вы можете использовать модальные окна, журналы, перенаправления или троллфейсы, но вы не собираетесь использовать alert(). - person Kyll; 30.06.2015
comment
Это было именно то, что я искал. СПАСИБО. Оповещение не будет вызвано, но форма не может быть отправлена ​​до полной проверки. Очень хорошее объяснение того, как FF обрабатывает оповещения. - person chillichief; 30.06.2015

предотвращение окон предупреждений в ff, вызывающих ошибки js, а иногда js вообще перестают работать после этого, поэтому ваш return false; не выполняется, попробуйте что-то вроде

function check(event){
    event = window.event || event;
    event.preventDefault(); 
    alert("asdf");
    return false;
}
<form action='#' onsubmit='check(event)'>
    <input type='text' name='asdf'/>
    <input type='submit' name='jkl' value='Submit'/>
</form>

person Pepo_rasta    schedule 30.06.2015

Использование console.log будет работать каждый раз, но алерт может быть заблокирован, и функция не будет вызываться.

Вы можете отобразить свое собственное оповещение, если вам нужно.

Вероятно, вам следует переместить обработчик событий из встроенного:

HTML:

<form action='#' id="my-form">
    <input type='text' name='asdf'/>
    <input type='submit' name='jkl' value='Submit'/>
</form>

JS:

document.getElementById('my-form').onsubmit = function() {
    console.log("asdf");
    return false;
}

Firefox remove содержит функцию, содержащую alert, поэтому вам нужно переместить alert out of your function:

Это позволит вам вернуть значение false, даже если оповещение отключено!

document.getElementById('my-form').onsubmit = function() {
    console.log("asdf");
    displayAlert();
    return false;
}
function displayAlert() {
    alert("test");    
}

JsFiddle: http://jsfiddle.net/ghorg12110/nddtf13q/

Чтобы отобразить персонализированное оповещение:

Этот код отобразит настраиваемое окно оповещения, которое Firefox не может заблокировать с помощью div. Вы должны сделать немного CSS, чтобы сделать его таким, как вы хотите, но основная идея здесь:

HTML:

<form action='#' id="my-form">
    <input type='text' name='asdf' />
    <input type='submit' name='jkl' value='Submit' />
</form>
<div id="alertBox">
    <div id="alertContent">asdf</div>
    <button id="alertOK">OK</button>
</div>

CSS:

#alertBox {
    display:none;
    background: grey none repeat scroll 0 0;
    left: 50%;
    margin-left: -275px;
    position: fixed;
    text-align: center;
    width: 550px;
    z-index: 10;
}

JS:

document.getElementById('my-form').onsubmit = function () {
    displayAlert("asdf");
    return false;
}
function displayAlert(msg) {
    document.getElementById('alertContent').innerHTML = msg;
    document.getElementById('alertBox').style.display = "block";
    document.getElementById('alertOK').onclick = function () {
        document.getElementById('alertBox').style.display = "none";
    };
}

JsFiddle: http://jsfiddle.net/ghorg12110/dkruqsqv/

person Magicprog.fr    schedule 30.06.2015
comment
Это позволит вам вернуть false, даже если оповещение отключено! Вообще-то, нет. В вашей настройке displayAlert вызовет исключение в Firefox, если alert() был отключен, и анонимный обработчик остановит его выполнение. - person Kyll; 30.06.2015
comment
Однако вы можете изменить его на setTimeout(displayAlert, 0), чтобы выполнить его после возврата обработчика onSubmit. - person Kyll; 30.06.2015