Jquery ajax GET запрос выполняется дважды
У меня есть следующий запрос ajax, который выполняется одним нажатием кнопки:
<a href="javascript:test()"><img src="css/images/test.png"></a>
function test(){
console.debug("*");
$.ajax({
type: "GET",
dataType: "json",
url: '/path/to/url',
success: function(data){
console.debug("**");
},
error: function(jqXHR, status, error){
console.debug("*** " + status + " : " + error + " : " + jqXHR.status);
},
cache: false
});
}
Ответ на запрос занимает приблизительно 30 секунд для возврата. Тем не менее, запрос принимается и выполняется сервером дважды, как это видно из журналов apache. Временная метка запросов составляет 30 секунд, но запрос идентичен (например, _ _ = 1363692320782). Функция ответа на клик вызывается один раз, и обратный вызов ошибки вызывается один раз (ровно через 60 секунд после первоначального запроса), хотя ответ apache равен 200.
Эта проблема была воспроизведена в Samsung Galaxy S2, версия Android 2.3.5 в приложении для телефонных разговоров.
UPDATE - добавление записей журнала Apache из комментария ниже
1.2.3.4 - - [19/Mar/2013:14:07:59 +0000] "GET /pcapi/records/dropbox/08342hjg9gpqm7g/?_=1363702072225 HTTP/1.1" 200 11139 "-" "Mozilla/5.0 (Linux; U; Android 2.3.5; en-gb; GT-I9100 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
1.2.3.4 - - [19/Mar/2013:14:08:29 +0000] "GET /pcapi/records/dropbox/08342hjg9gpqm7g/?_=1363702072225 HTTP/1.1" 200 11139 "-" "Mozilla/5.0 (Linux; U; Android 2.3.5; en-gb; GT-I9100 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
UPDATE - adb logcat
I/Web Console(16747): * at file:///android_asset/www/js/mobile.js:1769
I/Web Console(16747): *** error : : 0 at file:///android_asset/www/js/mobile.js:1779
ОБНОВЛЕНИЕ - монитор TCP/IP
Загрузка запросов через монитор TCP/IP показывает, что оба запроса отправляются с ответом 200 для обоих.
Ответы
Ответ 1
Я столкнулся с этой точной проблемой с моим приложением, работающим на Android 2.3.5. Я мог только сделать вывод, что веб-просмотр повторил запрос после таймаута. Я не мог найти способ повлиять на продолжительность таймаута.
В конце концов, я переписал код таким образом, чтобы первоначальный запрос выделил асинхронный процесс на сервере и немедленно вернулся. Затем, с помощью setTimer на странице, я бы проверял состояние процесса сервера (опять же, сразу возвращаюсь). Когда статус будет "полным", страница переместится на следующий шаг.
Надеюсь, это поможет. Я, конечно, понимаю ваше разочарование в этом. Я провел пару дней, чтобы сразиться с ним.
Изменить: Возможно, это была статья, которая отправила меня в направлении асинхронного решения. Я считаю, что проблема, заявленная здесь, одна и та же:
Проблема с двойной публикацией XmlHttpRequest в Android
Ответ 2
Если ваш путь URL, указанный здесь url: '/path/to/url'
, относится к папке, а не к определенному файлу, попробуйте добавить конечную косую черту, подобную этой url: '/path/to/url/'
.
Что происходит, когда файл не указан, веб-сервер Apache отправляет 301 переадресацию клиенту AJAX с новым URL (с завершающей косой чертой), поэтому клиент выдает новый запрос на правильный URL.
См. аналогичный вопрос, размещенный здесь: jQuery $.ajax() выполняется дважды?
См. ссылку на адрес Apache: http://httpd.apache.org/docs/2.0/mod/mod_dir.html#directoryslash
Ответ 3
Как насчет использования beforeSend:
и complete:
И .ajaxSend()
+ ajaxSuccess()
, попробуйте также с cache: true
$(document).ajaxSend(function (event, jqxhr, settings) {
console.log("triggered ajaxSend !");
if ( submission_active == true ) {
jqxhr.abort();
}
submission_active = true;
});
$(document).ajaxSuccess(function (event, xhr, settings) {
console.log("triggered ajaxSuccess !");
submission_active = false;
});
$.ajax({
type: "GET",
dataType: "json",
timeout: 30000,
cache: false,
url: '/path/to/url',
success: function(data){
console.debug("**");
},
beforeSend: function(xhr, opts){
if(submission_active == true){
xhr.abort();
}
submission_active = true;
},
complete: function(){
submission_active = false;
}
error: function(jqXHR, status, error){
console.debug("*** " + status + " : " + error);
}
});
Ответ 4
Я пробовал это на своем мобильном сайте, но проблема была в моей форме, а затем на моем javascript, который я объявил
$("#button_submit").onclick(function(){
//ajax request here
});
а также не забывайте удалить атрибуты формы, такие как действие и метод, если вы используете ajax
Надеюсь, это поможет вам ^ _ ^
Ответ 5
Событие Click запускается дважды. Этот код устраняет эту проблему.
$('.selector').unbind('click').bind('click', function () {
//...
// Ajax code
//...
});
Ответ 6
<a href="javascript:test()">
это ваша проблема. Если вы собираетесь использовать jquery, используйте их селектора css!!!!!!!! что href: материал javascript не работает в браузерах/устройствах.
Ответ 7
Звучит скорее как проблема распространения событий. У меня наблюдались подобные симптомы (хотя и на ios), и он сводился к событиям "touchstart" и "touchhend", которые запускали событие 'click'. Вы пробовали что-то вроде этого:
$("a").click(function (e) {
e.preventDefault();
alert('Clicked');
test();
});
Надеюсь, что это поможет!
Приветствия
JD
Ответ 8
Проблема, с которой вы сталкиваетесь, обычно называется "отскоком", она также сталкивается с переключателями в электронике, когда вы нажимаете и отпускаете кнопку, переключатель запускается дважды, поэтому вам нужно либо установить задержку для функции, либо отменить ее как только вы закончите с кликом.
Вы можете использовать дроссель демона Ben Alman script, чтобы отбросить ваши клики, это очень полезно для предотвращения множества вызовов ajax, объединить это с задержкой, и ваша проблема должна быть исправлена.
http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
var debounceClick = $.debounce(test, 1000);
function test() {
console.debug("*");
$.ajax({
type: "GET",
dataType: "json",
url: '/path/to/url',
success: function(data){
console.debug("**");
},
error: function(jqXHR, status, error){
console.debug("*** " + status + " : " + error + " : " + jqXHR.status);
},
cache: false
});
}
Теперь вызовите функцию debounceClick из ссылки, чтобы исправить вашу проблему.
В качестве альтернативы вы также можете использовать простой простой javascript без плагина дроссельной заслонки, чтобы добиться результата:
var timeout;
function test(){
console.debug("*");
$.ajax({
type: "GET",
dataType: "json",
url: '/path/to/url',
success: function(data){
console.debug("**");
},
error: function(jqXHR, status, error){
console.debug("*** " + status + " : " + error + " : " + jqXHR.status);
},
cache: false
});
}
function click() {
if(timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(test, 1000);
}
В этом примере привяжите функцию click() к вашей ссылке.
Ответ 9
Я столкнулся с той же проблемой, я связал событие click на кнопке отправки, а ajax запускается дважды.
Вместо привязки события я использовал метод onClick
на кнопке, как показано ниже
<button onclick"myProcess()"></button>
и он решает мою проблему.