#javascript #jquery #ruby-on-rails #internet-explorer
#javascript #jquery #ruby-on-rails #internet-explorer
Вопрос:
Я пишу приложение Rails 2.3.8 и использую стандартный link_to
помощник. У меня есть разумное количество ссылок, которые пользовательские методы, отличные от GET, не получают, поэтому я передаю :method => :whatever
опцию link_to
, и она генерирует ссылку с обработчиком onclick следующим образом (отступ добавлен для удобства чтения):
<a
onclick="
var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = this.href;
var s = document.createElement('input');
s.setAttribute('type', 'hidden');
s.setAttribute('name', 'authenticity_token');
s.setAttribute('value', '31M3q8SJkRz7f0R80l42Z2W7O2N7ZrzufhWQYql/Zd8=');
f.appendChild(s);
f.submit();
return false;"
href="/transactions/1015/transcribe"
>
Enter Data
</a>
Теперь, по какой-то причине, IE (оба 7 и 8 — два, которые я тестировал) решил, что return false;
в конце недостаточно, чтобы остановить переход по ссылке, и в итоге я получаю два запроса на свой сервер: запрос POST от обработчика onclick, который мне нужен, и запрос GET от самой ссылки, которого у меня нет. Фактически, этот маршрут не существует ни для чего, кроме запроса POST, поэтому, когда браузер выполняет запрос GET, пользователь попадает на экран с ошибкой «Неверный URL». Нехорошо.
Кто-нибудь видел это раньше и может сказать мне, что является причиной этого? Или, что еще лучше, кто-нибудь знает хороший обходной путь?
PS: Я бы предпочел НЕ
- Обезьяний патч
link-to
, или - Напишу свою собственную версию
link_to
но если это то, что требуется, это то, что требуется. И я использую jQuery 1.5.что-нибудь, если это поможет.
Комментарии:
1. большой проблемой здесь является встроенный javascript. Речь идет не о том, чтобы быть ненавязчивым, но, по крайней мере, обернуть это как функцию. Это некрасиво
2. Я удивлен, что что-то еще запускается после публикации формы. Может быть, попробовать preventDefault для объекта event перед отправкой формы? Также согласен с добавлением функции в. Редактировать: Ах, на самом деле не обрабатывал link_to, который генерировал это.
3. @fl00r — Если бы я это написал, это было бы. К сожалению, это результат
link_to
помощника Rails (если вы используете HTTP-глагол, отличный от GET), и я надеюсь избежать написания своего собственного.4. Проблема в том, что вы отправляете свою форму. Отправка формы перенаправляет вас на ее действие, которое совпадает с вашим href.
5. Я не уверен, вписывается ли это в мир ruby… но в jQuery мы часто используем «event.preventDefault();», чтобы предотвратить отправку формы. Я не уверен, насколько вы контролируете код, сгенерированный в событии click, но считаете ли вы, что это может быть полезно?
Ответ №1:
В общем, когда IE решает «игнорировать» return false;
из onclick
обработчика, это происходит потому, что одна из строк перед return false;
выдала исключение. Это вызовет автоматический сбой onclick
обработчика, и затем браузер попытается получить доступ к href
ссылке. Это относится ко всем браузерам, а не только к IE, но часто бывает так, что IE выдает исключения в тех случаях, когда другие браузеры этого не делают, поэтому кажется, что только IE игнорирует return false;
.
Одним из быстрых исправлений для этого является установка href="#"
, которая сохранит браузер на странице, даже если onclick
обработчик завершится неудачей. Однако правильный способ ее отладки — обернуть ваш onclick
код во что-то вроде try { ... } catch (ex) { alert(ex); }
, чтобы увидеть, что такое исключение, а затем исправить onclick
код, чтобы он больше не вызывал исключение.
Комментарии:
1. Голосую за несколько отличных предложений. К сожалению, тот факт, что Rails генерирует JS, усложняет их: я не могу изменить HREF, поскольку это то, что JS Rails использует для действия формы. Я попробую обернуть обработчик в блок try / catch своим собственным JS и опубликовать обратно с результатами…
2. Хм. После долгих экспериментов я, наконец, получил завернутую вещь, но она не перехватила никаких исключений. Даже когда я заменил обработчик простым «return false;», IE по-прежнему игнорировал его. Я буду продолжать искать…
3. Я получаю IE, выполняющий ссылку, которая не имеет ничего, кроме
onclick="return false"
в обработчике событий, так что это не [только] для исключений в обработчике onclick. В этом случаеid
привязка была «неопределенной» (динамически сгенерированный HTML-код —id="undefined"
когда я перешел и просмотрел в Firebug), и это неинтуитивно сбивало с толку. HTML был создан и записан на экран (о чем свидетельствует его рендеринг и переход IE по URL ссылки), но это предыдущее исключение, похоже, зависало.4. У меня тоже произошло на FF, если функция перед
return false;
завершается с ошибкой (даже беззвучно), то она все равно переходит по ссылке.
Ответ №2:
Чтобы предотвратить отправку формы в jQuery, мы часто используем
event.preventDefault();
Итак, в вашем примере вы могли бы использовать это (как обсуждалось в комментариях) :
$('a[onclick]').click(function(e) {e.preventDefault();});
Надеюсь, это поможет!
Комментарии:
1. И в качестве примечания для не-jQueriers: возврат false из этого обработчика событий также, похоже, сработал (хотя я придерживался версии jQuery, поскольку она, скорее всего, будет кроссбраузерной).
Ответ №3:
У меня была эта проблема с IE раньше, и я обнаружил, что решение, которое работает (которое, я полагаю, является тем, что jQuery event.preventDefault() делает под прикрытием), заключается в том, чтобы выполнять ОБА return false;
для обычных браузеров, но также event.returnValue = false;
(очевидно, до фактического return
) для IE. IE будет уважать это.
К сожалению, я не знаю, как вставить это в помощник link_to, не взломав его. Это на самом деле то, что я пришел сюда искать. 🙂
Ответ №4:
Я считаю, что проблема в том, что вы отправляете свою новую форму:
f.submit();
и вы отправляете это прямо в свою ссылку href
f.action = this.href;
итак, вы следуете по этому адресу. Ваша ссылка возвращает false, но отправленная форма приводит вас к этому местоположению.
Итак, с link_to
вами все в порядке. Проблема внутри вашего странного javascript.
Комментарии:
1. Это правильный адрес, и он должен «следовать» после отправки формы (запрос POST). Проблема в том, что после отправки формы IE сохраняет событие click активным, и браузер завершает выполнение второго (ошибочного) запроса GET, который
return false;
должен был предотвратить.2. О, я понял. Очень странно. Но необходимо протестировать
3. Я делаю! Пример кода является результатом
<%= link_to 'Enter Data', transcribe_transaction_path(txn), :method => :post %>
. Вот что делает это таким раздражающим (помимо необходимости работать с IE): я не могу изменить JS без обезьяньих исправлений Rails, и я бы действительно предпочел этого не делать.4. 2.3.8 (Хотя я начинаю думать, что ошибка где-то совсем в другом месте — что-то касательное, например, несоответствие тегов, может быть …)