2017-05-10 32 views
5

Mam spojrzał na wątkuAjax upload plików zwraca kod stanu 0 gotowy stan 0 (tylko czasami)

jQuery Ajax - Status Code 0?

Jednak nie mogłem znaleźć ostateczną odpowiedź i mam poważne kłopoty próbuje znaleźć źródło mojego problemu, więc zamieszczam tutaj w nadziei, że ktoś może wskazać mi właściwy kierunek.

W moim kodzie wykonuję angular HTTP post, który po prostu wysyła podstawowe dane JSON, a następnie w callback na żądanie używam AJAX do przesyłania plików na ten sam serwer. (Wiem, że nie powinno być przy użyciu jQuery i kątowe jednak nie mogę zmienić na chwilę)

Wygląda to mniej więcej tak to

var deferred = $q.defer() 

// first post 
$http.post(url,payload,{params: params, headers: headers) 
    .then(function(response) { 

    uploadFiles(response,deferred); 
    // I am also sending google analytics events here 

    }, function(error) { 
     // do error stuff 
    } 

    return deferred.promise; 

// upload files function 
function uploadFiles(response,deferred){ 

$ajax({ 
    type: 'POST', 
    processData: false, 
    contentType: false, 
    data: data // this new FormData() with files appended to it, 
    url: 'the-endpoint-for-the-upload', 
    dataType: 'json', 
    success: function(data) { 
    // do success stuff here 
    deferred.resolve(data); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 

      var message = {}; 

      if (jqXHR.status === 0) { 
       message.jqXHRStatusIsZero = "true"; 
      } 

      if (jqXHR.readyState === 0) { 
       message.jqXHRReadyStateIsZero = "true"; 
      } 

      if (jqXHR.status === '') { 
       message.jqXHRStatusIsEmptyString = "true"; 
      } 

      if (jqXHR.status) { 
       message.jqXHRStatus = jqXHR.status; 
      } 

      if (jqXHR.readyState) { 
       message.jqXHRReadyState = jqXHR.readyState; 
      } 

      if (jqXHR.responseText) { 
       message.jqXHR = jqXHR.responseText; 
      } 

      if (textStatus) { 
       message.textStatus = textStatus; 
      } 

      if (errorThrown) { 
       message.errorThrown = errorThrown; 
      } 

      message.error = 'HTTP file upload failed'; 

      logError(message); 

      deferred.resolve(message); 
     } 
    } 
}) 

} 

Nie moim dokładnym kodem ale prawie dokładnie to samo.

Problem polega na tym, że działa prawie przez cały czas, ale może trzy lub cztery na każde kilkaset zawiodą. Przez niepowodzenie rozumiem, że funkcja obsługi błędów jest wywoływana w funkcji przesyłania plików, a pliki nie są przesyłane.

Otrzymuję jqXHRStatus 0 i jqXHRReadyState 0, kiedy to nastąpi.

Jedynym sposobem jestem w stanie replikować problemu jest przez uderzanie odświeżenia w przeglądarce, gdy żądanie jest przetwarzane, jednak użytkownicy poinformowali, że nie są to robią (choć trzeba 100% to potwierdzić)

Czy jest jakiś poważny błąd w moim kodzie, którego nie widzę? Może przekazanie zmiennej odroczonej nie jest dobrą praktyką? Lub inny sposób anulowania żądania ajax, którego nie rozważam? Czy wysyłanie zdarzeń Google Analytics może być zakłócane w tym samym czasie?

Każda porada byłaby świetna i daj mi znać, jeśli chcesz uzyskać więcej informacji na ten temat.

+1

może się zdarzyć, jeśli strona jest włączony podczas wniosek lub może, jeśli nie jest w pełni załadowany i wniosek już zaczyna? Może się zdarzyć, jeśli dane nie są o.k.? Czy jest jakieś zdarzenie, które może przerwać żądanie? Jesteś pewien, że nic z tego nie jest prawdą? Ponieważ coś musi przerwać żądanie podczas przetwarzania, jak sądzę. – Blackbam

+0

jak radzisz sobie z błędami back-end? Może pokaże kod backend też – alepeino

+0

możesz uzyskać więcej informacji, jeśli przeglądasz przeglądarki devtools konsoli po replikacji problem jest przez naciśnięcie odświeżenia w przeglądarce. Karta Sieć może również zawierać dodatkowe informacje (opcja XHR). – KorreyD

Odpowiedz

0

Domyślam się, że Twój kod jest wykonywany, zanim faktycznie wróci z połączenia. To znaczy. połączenie wraca, a nic nie jest zwracane i daje błąd 0. Miałoby to sens, ponieważ błąd jest zmienny. Przez większość czasu zwracał się dobrze, ponieważ backend był wykonywany wystarczająco szybko, ale czasami nie, ponieważ trwało to wyjątkowo długo lub coś innego się wydarzyło itd. Javascript nigdy nie przestaje NAPRAWNIE wstrzymywać egzekucji. Mówi, że robi to, ale szczególnie przechodząc między kątowym a jquery z wieloma żądaniami ajaxowymi, nie byłoby zaskoczeniem, gdyby wykonywał drugie wywołanie ajaxowe, zanim faktycznie wypełnił twój kątowy post. Dlatego odświeżenie spowoduje odtworzenie błędu, ponieważ spowoduje wyczyszczenie zmiennych.

Niektóre rzeczy można zrobić, aby to sprawdzić:

  1. na backend sprawiają, timer, który przechodzi przez kilka sekund zanim powróci nic. Prawdopodobnie spowoduje to, że Twój kod przestanie działać bardziej konsekwentnie.

  2. Ustaw punkty przerwania i zobacz, kiedy są one trafiane, oraz wartości, które zawierają w javascript.

Powodzenia!

2

Oznacza to, że żądanie zostało anulowane.

Może być wiele różnych powodów, ale należy pamiętać: może to być spowodowane błędem lub błędem przeglądarki - wierzę więc (IMHO), że nie ma sposobu, aby zapobiec tego rodzaju problemom.

Pomyśl na przykład, otrzymasz odpowiedź 503 (Usługa niedostępna). Co byś zrobił w takim przypadku? Jest to również sporadyczny i niemożliwy do przewidzenia problem. Po prostu żyj z tym i spróbuj ponownie przesłać dane.

Bez wyważania otwartych drzwi, proponuję wdrożyć: Retrying ajax calls using the deferred api