Żądania jQuery Ajax są anulowane bez wysyłania

87

Próbuję podłączyć skrypt do aplikacji Microsoft World-Wide Telescope. Ten ostatni nasłuchuje na porcie 5050 w poszukiwaniu poleceń. Działa na tym samym komputerze co przeglądarka (obecnie Chrome, ale o ile wiem, zachowanie jest takie samo w przypadku przeglądarek Firefox 7 i IE 9).

Wysyłam nagłówek „Access-Control-Allow-Origin: *” z oryginalnym plikiem html, aby spróbować wyeliminować ograniczenia XSS jako mój problem.

Mój kod dostępu do WWT jest następujący:

$.ajax({
    type: 'POST',
    url: url,
    data: data,
    crossDomain: true,
    success: success,
    dataType: dataType
});

url w tym przypadku to „http: //127.0.0.1: 5050 / layerApi.aspx? cmd = new & ...” (oczywiście… jest tutaj skrótem dla kilku dodatkowych parametrów).

Patrząc na diagnostykę sieci w Chrome, widzę to:

Request URL:http://127.0.0.1:5050/layerApi.aspx?cmd=new&...
Request Headersview source
Accept:application/xml, text/xml, */*; q=0.01
Content-Type:application/x-www-form-urlencoded
Origin:http://gwheeler4
Referer:http://gwheeler4/conceptconnect.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1

Żądanie wychodzi - widzę, że WWT tworzy nową warstwę. Jednak nie otrzymuję oddzwonienia. Jeśli dodam wywołanie zwrotne błędu, które jest wywoływane, ale właściwość błędu w obiekcie jqXHR to po prostu „błąd”, a stan wynosi 0. Jeśli spojrzę na żądanie sieciowe w Chrome, widzę „(anulowano)” jako stan i brak odpowiedzi .

Jeśli wezmę ten sam adres URL i wkleię go w nowej karcie przeglądarki, widzę, że odpowiedź to oczekiwany kod XML.

Oczywiście różnica polega na tym, że jest to GET, a nie POST, ale próbowałem tego w moim skrypcie i nie ma to znaczenia.

Jestem tym dość zaskoczony i byłbym wdzięczny za wszelkie świeże pomysły.

Graham Wheeler
źródło
Czy próbowałeś obsługiwać errorwywołanie zwrotne, aby sprawdzić, czy powraca z błędem?
StriplingWarrior
1
„Wysyłam nagłówek„ Access-Control-Allow-Origin: * ”z oryginalnym plikiem html, aby spróbować wyeliminować ograniczenia XSS jako mój problem.” Czy masz na myśli, że serwer odsyła nagłówek Access-Control-Origin? Albo że wysyłasz go wraz z żądaniem Ajax?
Jason Dean
spróbuj wejść na stronę bezpośrednio przez adres URL i zobacz, czy
wyciągasz
1
Tak, otrzymuję informację zwrotną o błędzie z tekstem statusu „” i kodem 0. To nie jest problem z jQuery; Przepisałem kod używając prostego XHR i otrzymałem ten sam wynik - tj. ReadyState 4 z request.status równym zero i pustym request.responseText. Nagłówek Access-Control-Allow-Origin jest wysyłany przez serwer. Dostęp do strony bezpośrednio przez adres URL zwraca oczekiwaną odpowiedź XML.
Graham Wheeler

Odpowiedzi:

134

Jeśli ktokolwiek napotkał ten problem, problem polegał na tym, że wysyłaliśmy żądanie Ajax z łącza i nie uniemożliwialiśmy śledzenia tego łącza. Więc jeśli robisz to w onclickatrybucie, upewnij się, że return false;również.

Kazetsukai
źródło
U mnie też to zadziałało. Dzięki. Zapomniałem, dlaczego zwracałem false w moim module obsługi onClick i zmieniłem go na true, a po przeczytaniu twojego postu nagle dotarło do mnie.
Shiprack
4
Dodatkowo, jeśli korzystasz z formularza, musisz dodać atrybut return falsena końcu swojego onsubmit.
Jason Axelson
8
@VincentClyde "return false;"informuje formularze i linki, aby przerwać akcję. Było to pierwotnie przeznaczone do walidacji formularza javascript, gdzie funkcja walidacji zwróciłaby fałsz, jeśli formularz byłby nieprawidłowy, zatrzymując przesyłanie formularza.
Tyzoid
13
Możesz również użyć e.preventDefault();, gdzie ejest onclickparametrem zdarzenia.
Hannele
1
@Hannele Dziękuję bardzo za udostępnienie event.preventDefault. Tak bardzo tego potrzebowałem. Nie widzę innej odpowiedzi, która to sugeruje. Powinieneś to opublikować jako oddzielną odpowiedź.
Mohit
112

Jeśli używasz przeglądarki Chrome, w standardowym panelu sieci Chrome nie widać wystarczających informacji, aby określić podstawową przyczynę (canceled)żądania.

Musisz użyć, chrome://net-internals/#eventsktóry pokaże ci krwawe szczegóły wysyłanego żądania - w tym ukryte przekierowania / informacje bezpieczeństwa dotyczące wysyłanych plików cookie itp.

na przykład poniżej przedstawiono przekierowanie, którego nie widziałem w śledzeniu sieci - spowodowane tym, że moje pliki cookie nie były wysyłane między subdomenami:

t=1374052796448 [st=  1]   +URL_REQUEST_START_JOB  [dt=261]
                            --> load_flags = 143540481 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VALIDATE_CACHE | VERIFY_EV_CERT)
                            --> method = "GET"
                            --> priority = 2
                            --> url = "https://...."
...
t=1374052796708 [st=261]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                                --> HTTP/1.1 302 Moved Temporarily
                                    Content-Type: text/html
                                    Date: Wed, 17 Jul 2013 09:19:56 GMT
...
t=1374052796709 [st=262]     +URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=0]
t=1374052796709 [st=262]        CANCELLED
t=1374052796709 [st=262]   -URL_REQUEST_START_JOB
                            --> net_error = -3 (ERR_ABORTED)
Ben Walding
źródło
Mam też (anulowany) problem. @Ben, fajnie było dowiedzieć się o tym śladzie, niestety nie podał żadnych informacji. Serwer w moim przypadku to S3 i cors jest skonfigurowany na moim wiadrze. Wszystko, co robię, to proste GET dla obrazu. Widzę w panelu sieci żądanie z nagłówkiem Origin, ale bez odpowiedzi. Najwyraźniej Chrome anuluje żądanie przed wysłaniem go na serwer. Bez przekierowań, bez https, bez zawartości 0. Walenie w głowę przez cały dzień, wciąż jest tajemnicą.
Gene Vayngrib
@GeneVayngrib Wypróbuj Firefoksa - debugger sieci bezpośrednio pokaże więcej informacji - możesz tam rozwiązać problem, a następnie uruchomić go w Chrome.
Ben Walding,
@BenW dziękuję, ale Firefox nie ma problemu z tym obrazem, który jest udostępniany z Amazon S3.
Gene Vayngrib,
YUPP. To bardzo pomogło!
rubmz
21

W moim przypadku miałem type='submit'tak, gdy wysyłałem formularz, strona była przeładowywana przed trafieniem Ajaxa, więc proste rozwiązanie było mieć type="button". Jeśli nie określisz typu, jest on submitdomyślny, więc musisz określićtype="button"

type='submit' => type='button'

LUB

Brak typu => type='button'

Czarna Mamba
źródło
3
Necro publikuje tutaj, pozwól mi stackoverflow. Szukałem wysoko i nisko przez cały dzień, dlaczego moja prośba działa z konsoli, ale nie ze skryptu, i to była odpowiedź ... dziękuję !!!
pcort
1
Zalogowałem się i ponownie znalazłem ten wątek, aby zagłosować za tą odpowiedzią !!, to bardzo pomogło. łamał mi głowę na wiele godzin
dev
Jai shree krishna, mam nadzieję, że pomoże to wielu przyjść. I ustalają wcześniej.
Black Mamba
6

Miałem podobny problem. W moim przypadku próbuję użyć usługi WWW na serwerze Apache + django (usługa została napisana przeze mnie). Miałem taki sam wynik jak ty: Chrome twierdzi, że został anulowany, podczas gdy FF robi to dobrze. Gdybym próbował uzyskać dostęp do usługi bezpośrednio w przeglądarce zamiast Ajax, to również zadziałałoby. Rozglądając się po Google, odkryłem, że niektóre nowsze wersje Apache nie ustawiały poprawnie długości odpowiedzi w nagłówkach odpowiedzi, więc zrobiłem to ręcznie. Z django wszystko co musiałem zrobić to:

response['Content-Length'] = len(content)

Jeśli masz kontrolę nad usługą, do której próbujesz uzyskać dostęp, dowiedz się, jak zmodyfikować nagłówek odpowiedzi na używanej platformie, w przeciwnym razie będziesz musiał skontaktować się z usługodawcą, aby rozwiązać ten problem. Wygląda na to, że FF i wiele innych przeglądarek jest w stanie poprawnie obsłużyć tę sytuację, ale projektanci Chrome postanowili zrobić to zgodnie z opisem.

Felipe Sodre Silva
źródło
Próbowałem ustawić nagłówek długości treści i nadal mam ten sam problem, który został opisany w pierwotnym pytaniu. Używam PHP 5.3.8 i Apache 2.2.21 (używam WAMP w Windows 7)
rodrigo-silveira
4

Miałem podobny problem. Korzystając z chrome: // net-internals / # events mogłem zobaczyć, że mój problem jest spowodowany cichym przekierowaniem. Moje żądanie get było uruchamiane w skrypcie onload. Adres URL miał postać „ http://example.com/inner-path ”, a 301 stale przekierowywał do „/ internal-path”. Aby rozwiązać problem, po prostu zmieniłem adres URL na „/ internal-path” i to rozwiązało problem. Nadal nie wiem, dlaczego skrypt, który działał tydzień temu, nagle dał mi problem ... Mam nadzieję, że to komuś pomoże

RedEight
źródło
3

(Korzystanie z formularzy sieci Web ASP.NET)

Mój problem polegał na tym, że próbowałem zwolnić Ajax ze zdarzenia kliknięcia przycisku przesyłania, który miał konfigurację zdarzenia kliknięcia po stronie serwera. Musiałem uczynić przycisk tylko prostym przyciskiem (tj. <input type="button">)

contactmatt
źródło
Dziękuję Ci bardzo.
Farheen Nilofer
3

Miałem ten sam problem, dla mnie tworzyłem iframe na tymczasowy sposób i usuwałem iframe zanim Ajax się zakończy, więc przeglądarka anuluje moje żądanie Ajax.

Reza
źródło
Jak rozwiązałeś ten problem? Moja witryna jest osadzana w ramce iFrame, która nie jest przeze mnie kontrolowana. Chcę, aby moje połączenie zostało zakończone, ponieważ ma pewne ustawienia danych w tle
Rips
@Rips to było 4 lata temu, w każdym razie myślę, że rozwiązałem to za pomocą Promises
Reza
3

Rozwijając odpowiedź @ Kazetsukai, możesz napotkać ten problem, jeśli wysyłasz żądanie AJAX od użytkownika klikającego łącze.

Jeśli skonfigurujesz swój link w ten sposób:

<a href="#" onclick="soAjax()">click me!</a>

A następnie program obsługi javascript, taki jak następujący:

soAjax() {
    $.ajax({ ... all your lovely parameters ... });       
}

Aby uniemożliwić przeglądarce skorzystanie z łącza i anulowanie wszelkich żądań w toku, należy dodać return falselub e.preventDefault()zatrzymać propagację zdarzenia kliknięcia:

soAjax() {
   $.ajax({ ... etc ... });
   return false;
}

Lub:

soAjax(e) {
   $.ajax({ ... etc ... });
   e.preventDefault();
}
Hannele
źródło
2

Istnieją dwie możliwości, gdy żądanie AJAX zostaje odrzucone (jeśli nie jest to żądanie Cross-Origin):

  1. Nie zapobiegasz domyślnemu zachowaniu elementu dla zdarzenia.
  2. Ustawiono zbyt niski limit czasu AJAX lub serwer zaplecza sieciowego / aplikacji działa wolno.

Rozwiązanie dla 1) : Dodaj return false;lub e.preventDefault();w programie obsługi zdarzeń.

Rozwiązanie dla 2) : Dodaj opcję limitu czasu podczas tworzenia żądania AJAX. Przykład poniżej.

$.ajax({
    type: 'POST',
    url: url,
    timeout: 86400,
    data: data,
    success: success,
    dataType: dataType
});

W przypadku żądań między źródłami sprawdź nagłówki HTTP udostępniania zasobów między źródłami (CORS).

AnkitK
źródło
1

Wystąpił ten błąd podczas wysyłania żądania przy użyciu protokołu http do adresu URL wymagającego protokołu https. Myślę, że wywołanie Ajax nie obsługuje przekierowania. Dzieje się tak nawet w przypadku opcji crossDomain ajax ustawionej na true (w JQuery 1.5.2).

ptutt
źródło
0

W moim przypadku mod-rewrite I Apache pasował do adresu URL i przekierowywał żądanie do https.

Spójrz na żądanie w chrome: // net-internals / # events.

Pokaże wewnętrzny dziennik żądania. Sprawdź przekierowania.

bbrame
źródło
0

Miałem ten sam problem, ale w moim przypadku okazał się to problem z ciasteczkami. Faceci pracujący na zapleczu zmienili ścieżkę do pliku cookie JSESSIONID, który jest ustawiany, gdy logujemy się do naszej aplikacji, i miałem na komputerze stary plik cookie o tej nazwie, ale ze starą ścieżką. Kiedy więc próbowałem zalogować się w przeglądarce (Chrome), wysłałem do serwera dwa ciasteczka o nazwie JSESSIONID, o różnych wartościach - co zrozumiałe go pomieszało - więc anulował żądanie. Usunięcie plików cookie z mojego komputera naprawiło to.

Joe Dyndale
źródło
0

Miałem ten błąd w bardziej upiorny sposób: karta sieci i zdarzenia chrome: // net-internals / # nie wyświetlały żądania po ukończeniu js. Podczas wstrzymywania js w wywołaniu błędu karta sieci wyświetlała żądanie jako (anulowane). Konsekwentnie wywoływano dokładnie jedno (zawsze takie samo) z kilku podobnych żądań na stronie internetowej. Po ponownym uruchomieniu Chrome błąd już się nie pojawił!

chrześcijanin
źródło
0

Miałem anulowane w przeglądarce Firefox . Niektóre wywołania Ajaxa działały doskonale dla mnie, ale zawiodły u współpracownika, który musiał go używać.

Kiedy sprawdziłem to za pomocą wspomnianych powyżej sztuczek Chrome, nie znalazłem nic podejrzanego. Podczas sprawdzania tego w firebugu pokazywał animację „ładowania” po dwóch metalicznych wywołaniach i bez zakładki wyników.

Rozwiązanie było mega proste: przejdź do historii, znajdź stronę, kliknij prawym przyciskiem -> zapomnij stronę.
Zapomnij, nie usuwaj.

Potem już żadnych problemów. Domyślam się, że ma to coś wspólnego z .htaccess.

Martijn
źródło
0

W moim przypadku był to brakujący końcowy ukośnik w adresie URL. Dodanie końcowego ukośnika rozwiązało mój problem.

Aftab Baig
źródło
0

W przypadku Dropzone.js. W moim przypadku było to spowodowane tym, że wartość timeoutopcji była domyślnie zbyt niska. Więc zwiększ go według swoich potrzeb.

{
// other dropzone options
timeout: 60000 * 10, // 10 minutes
...
}
Scofield
źródło
-1

Miałem ten problem z określoną siecią 3G.
Zawsze kończyło się niepowodzeniem w przypadku żądań DELETE net_error = -101w chrome: // net-internals / # events.

Inne sieci działały dobrze, więc zakładam, że był uszkodzony serwer proxy lub coś takiego.

Dan Abramov
źródło