O czym jest sieć :: ERR_HTTP2_PROTOCOL_ERROR?

36

Obecnie pracuję nad witryną, która powoduje net::ERR_HTTP2_PROTOCOL_ERROR 200błąd w Google Chrome. Nie jestem pewien, co dokładnie może sprowokować ten błąd, zauważyłem, że wyskakuje on tylko podczas uzyskiwania dostępu do witryny w HTTPS. Nie mogę być w 100% pewien, że jest on powiązany, ale wygląda na to, że uniemożliwia to prawidłowe wykonanie javascript.

Na przykład dzieje się następujący scenariusz:

  1. Uzyskuję dostęp do strony w HTTPS

  2. Mój kanał na Twitterze zintegrowany przez https://publish.twitter.com nie jest w ogóle ładowany

  3. W konsoli mogę zauważyć ERR_HTTP2_PROTOCOL_ERROR

  4. Jeśli usunę kod, aby załadować kanał Twitter, błąd pozostanie

  5. Jeśli uzyskam dostęp do strony w HTTP, pojawi się kanał na Twitterze, a błąd zniknie

Google Chrome to jedyna przeglądarka internetowa powodująca błąd: działa dobrze zarówno w Edge, jak i Firefox. (Uwaga: próbowałem z Safari i mam podobny kcferrordomaincfnetwork 303błąd)

Zastanawiałem się, czy może to być związane z nagłówkiem zwróconym przez serwer, ponieważ w błędzie jest wzmianka o „200”, a strona 404/500 niczego nie wyzwala.

Chodzi o to, że błąd wcale nie jest udokumentowany. Wyszukiwarka Google daje mi bardzo mało wyników. Ponadto zauważyłem, że pojawia się w najnowszych wydaniach Google Chrome; błąd nie pojawia się w wersji 64.X, ale występuje w wersji 75. + (niezależnie od systemu operacyjnego; pracuję na komputerze Mac).

Wszelkie wskazówki w tym miejscu do zbadania byłyby mile widziane!

Z góry dziękuję.

Tristan


Edycja 1: Może być powiązany z witryną OK w przeglądarce Firefox, ale nie w przeglądarce Safari (kCFErrorDomainCFNetwork error 303) ani w Chrome (netto :: ERR_SPDY_PROTOCOL_ERROR)


Edycja 2: Wyniki dalszych badań są następujące:

  • błąd nie pojawia się na tej samej stronie, jeśli serwer zwraca 404 zamiast 2XX
  • błąd nie pojawia się lokalnie z certyfikatem HTTPS
  • błąd pojawia się na innym serwerze (oba są OVH), który używa innego certyfikatu
  • pojawia się błąd bez względu na to, jaka wersja PHP jest używana, od 5.6 do 7.3 (użyte ramy: Cakephp 2.10)

Edycja 3: Zgodnie z żądaniem poniżej znajduje się zwrócony nagłówek informujący o awarii zasobu, którym jest cała strona internetowa. Nawet jeśli błąd pojawia się na każdej stronie mającej nagłówek HTTP 200, strony te zawsze ładują się w przeglądarce klienta, ale czasami brakuje elementu (na przykład zewnętrznego kanału Twittera). Każdy inny zasób na karcie Sieć ma zwrot z powodzeniem, z wyjątkiem całego dokumentu. linia, która nie powiodła się w konsoli

Nagłówek Google Chrome (z błędem):

Nagłówek Chrome

Nagłówek Firefoksa (bez błędu):

Nagłówek Firefoksa

curl --head --http2Żądanie w konsoli zwraca następujący sukces:

HTTP/2 200 
date: Fri, 04 Oct 2019 08:04:51 GMT
content-type: text/html; charset=UTF-8
content-length: 127089
set-cookie: SERVERID31396=2341116; path=/; max-age=900
server: Apache
x-powered-by: PHP/7.2
set-cookie: xxxxx=0919c5563fc87d601ab99e2f85d4217d; expires=Fri, 04-Oct-2019 12:04:51 GMT; Max-Age=14400; path=/; secure; HttpOnly
vary: Accept-Encoding

Edycja 4: Próbuję wejść głębiej dzięki narzędziom chrome: // net-export / i https://netlog-viewer.appspot.com mówi mi, że żądanie kończy się RST_STREAM:

t=123354 [st=5170]    HTTP2_SESSION_RECV_RST_STREAM
                      --> error_code = "2 (INTERNAL_ERROR)"
                      --> stream_id = 1

W przypadku tego, co przeczytałem w tym drugim poście : „ W HTTP / 2, jeśli klient chce przerwać żądanie, wysyła RST_STREAM. Gdy serwer odbierze RST_STREAM, przestanie wysyłać ramki danych do klienta, zatrzymując w ten sposób odpowiedź (lub pobieranie). Połączenie jest nadal użyteczne w przypadku innych żądań, a żądania / odpowiedzi, które były zbieżne z tym, które zostało przerwane, mogą nadal się rozwijać. [...] Możliwe jest, że do czasu, gdy RST_STREAM podróżuje z od klienta do serwera, cała treść żądania jest przesyłana i dotrze do klienta, który go odrzuci. Jednak w przypadku treści o dużej odpowiedzi wysłanie RST_STREAM może mieć dużą szansę na dotarcie do serwera przed całą treść odpowiedzi jest wysyłana, co pozwala zaoszczędzić przepustowość.

Opisane zachowanie jest takie samo jak to, które mogę zaobserwować. Oznaczałoby to jednak, że winowajcą jest przeglądarka, a następnie nie rozumiem, dlaczego dzieje się to na dwóch identycznych stronach, z których jedna ma nagłówek 200, a druga 404 (to samo dotyczy wyłączenia JS).

Tristan G.
źródło
aboutssl.org/fix-google-chrome-error-err_ssl_protocol_error, który jest jednym ze 110 wyników -
Jaromanda X
Byłem tu oczywiście i są odpowiedzi tylko po stronie klienta, co nie może być rozwiązaniem.
Tristan G
Czy błąd występuje w przeglądarkach innych niż Chrome? jeśli nie, to dlaczego nie jest to problem po stronie klienta (w szczególności przeglądarki Chrum)?
Jaromanda X
1
Prawdopodobnie źle sformułowane nagłówki odpowiedzi HTTP. Czy cała strona się nie ładuje? Czy tylko jeden lub więcej zasobów? Czy możesz edytować pytanie, aby uwzględnić nagłówki odpowiedzi HTTP pokazane w odpowiedzi HTTP dla zasobu, który nie ładuje się przy użyciu HTTP / 2? A także dla Edge / Firefox, gdzie to działa?
Barry Pollard
1
Nie widzę tam nic złego, więc podejrzewam, że to nie jest główna prośba. Zignoruj ​​też ciasteczka - to nie to. Spróbuj tego, aby dowiedzieć się, czy możesz to rozwiązać: michalspacek.com/…
Barry Pollard

Odpowiedzi:

7

Przez kilka tygodni denerwował mnie również ten „błąd”:

net :: ERR_HTTP2_PROTOCOL_ERROR 200

W moim przypadku miało to miejsce na obrazach generowanych przez PHP.

Było na header()poziomie, a szczególnie na tym:

header ('Content-Length:'. Filesize($cache_file));

Oczywiście nie zwrócił dokładnego rozmiaru, więc go usunąłem i teraz wszystko działa dobrze.

Tak więc Chrome sprawdza dokładność danych przesyłanych przez nagłówki, a jeśli nie odpowiadają, nie powiedzie się.

EDYTOWAĆ

Dowiedziałem się, dlaczego przeliczono błąd content-lengthvia filesize: GZIPkompresja jest aktywna w plikach PHP, więc wykluczenie tego pliku naprawi problem. Umieść ten kod w .htaccess:

SetEnvIfNoCase Request_URI ^ / thumb.php no-gzip -vary

Działa i trzymamy nagłówek Content-length.

Xtendo
źródło
1
Świetnie mnie uratowałeś !!! Ale nadal nie rozumiem prawdziwego problemu, w moim przypadku błąd występuje tylko w https, ale nie w http.
Nico,
Witaj @Nico, tak, myślę, że to normalne, weryfikacja między ogłoszonym rozmiarem a rozmiarem pliku pobranego przez przeglądarkę (Chrome) powinna odbywać się tylko w protokole https. Bardzo się cieszę, że to rozwiązanie może ci pomóc!
Xtendo,
1
Jakoś udało mi się użyć „Content -Length” zamiast „Content-Length”. Po usunięciu przestrzeni zadziałało. Dziękuję Ci.
Martin Lottering
Cześć @Martin Lottering Bardzo się cieszę, że teraz działa dla Ciebie! :-)
Xtendo
6

Nie wiedziałem, co się właściwie dzieje, ale znalazłem rozwiązanie.

CDN cechą OVH był winowajcą. Miałem go zainstalowanego w usłudze hosta, ale wyłączono dla mojej domeny, ponieważ go nie potrzebowałem.

Jakoś, kiedy włączę, wszystko działa.

Myślę, że zmusza to Apache do korzystania z protokołu HTTP2, ale nie rozumiem tego, że rzeczywiście w każdym z moich nagłówków była wzmianka o HTTP2, co, jak sądzę, oznacza, że ​​serwer odpowiadał przy użyciu właściwego protokołu.

Tak więc rozwiązaniem dla mojego szczególnego przypadku było włączenie opcji CDN we wszystkich zainteresowanych domenach.

Jeśli ktokolwiek lepiej zrozumie, co mogło się tu wydarzyć, możesz podzielić się wyjaśnieniami.

Tristan G.
źródło
czyszczenie pamięci podręcznej cdn działało dla mnie
Varshaan
4

Napotkałem to, ponieważ serwer http2 zamknął połączenie podczas wysyłania dużej odpowiedzi do Chrome.

Dlaczego? Ponieważ jest to tylko ustawienie serwera http2 o nazwie WriteTimeout .

jedna książka
źródło
4

W moim przypadku było - brak miejsca na dysku na serwerze WWW.

Alex Kalmikov
źródło
ciekawe, dla mnie ten sam przedni serwer miał pełny dysk. wygląda na to, że nginx nie łapie tej sytuacji, ponieważ w logu nie było nic zauważalnego.
vchrizz
3

Wystąpił podobny problem, otrzymywałem ERR_HTTP2_PROTOCOL_ERROR na jednym z żądań HTTP GET.

Zauważyłem, że aktualizacja Chrome jest w toku, więc zaktualizowałem przeglądarkę Chrome do najnowszej wersji i błąd zniknął następnym razem, gdy uruchomiłem ponownie przeglądarkę.

Jaikumar
źródło
2

Miałem ten problem, gdy miałem serwer Nginx, który wystawiał aplikację node-js na świat zewnętrzny. Nginx sprawił, że plik (css, js, ...) został skompresowany za gzippomocą Chrome i wyglądał tak samo.

Problem rozwiązany, gdy okazało się, że serwer node-js również skompresował zawartość za pomocą gzip. W pewnym sensie to podwójne kompresowanie prowadzi do tego problemu. Anulowanie kompresji node-js rozwiązało problem.

No1Lives4Ever
źródło
6
Interesujące jest to, że kilka osób już odpowiedziało na ten post i za każdym razem źródło problemu było czymś innym. Myślę, że ten błąd jest rzeczywiście dość mylący.
Tristan G
2

Ten błąd jest obecnie naprawiany: https://chromium-review.googlesource.com/c/chromium/src/+/2001234

Ale pomogło mi to, zmieniając ustawienia nginx:

  • włączanie gzip;
  • add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age = 0';
  • wygasa;

W moim przypadku Nginx działa jako odwrotny serwer proxy dla aplikacji Node.js.

Eduardy
źródło
ta odpowiedź również działała dla mnie. Kliknij ten link docs.nginx.com/nginx/admin-guide/web-server/compression, aby uzyskać prawidłową składnię
Bhargavi Gopalachar
1

Zdarzyło mi się to, gdy zarejestrowałem nową nazwę domeny, np. „Nowy” na przykład.com (nowy.przyklad.com). Nazwa nie mogła zostać tymczasowo rozwiązana w mojej lokalizacji przez kilka godzin, podczas gdy można ją rozwiązać za granicą. Użyłem więc proxy do przetestowania witryny, w której widziałem net::ERR_HTTP2_PROTOCOL_ERRORw konsoli Chrome niektóre posty AJAX. Kilka godzin później, kiedy nazwa mogła zostać zapisana lokalnie, ten błąd zniknął.

Myślę, że przyczyną tego błędu jest to, że moje żądania AJAX nie zostały przekierowane przez mojego proxy, po prostu odwiedzają stronę internetową, która nie została rozwiązana przez mój lokalny serwer rozpoznawania nazw DNS.

Dzhuang
źródło
1

Napotkałem ten błąd kilka razy i wynikało to z przeniesienia dużych zasobów (większych niż 3 MB) z serwera na klienta.

Fereydoon Barikzehy
źródło
0

Otrzymałem ten sam problem (asp, c # - HttpPostedFileBase) podczas publikowania pliku, który był większy niż 1 MB (mimo że aplikacja nie ma żadnych ograniczeń co do wielkości pliku), dla mnie pomogło uproszczenie klasy modelu. Jeśli masz ten problem, spróbuj usunąć niektóre części modelu i sprawdź, czy to pomoże w jakikolwiek sposób. Brzmi dziwnie, ale działało dla mnie.

LV
źródło
0

Ten problem występuje od ostatniego tygodnia, gdy próbuję wysyłać żądania DELETE do mojego serwera PHP za pośrednictwem AJAX. Niedawno zaktualizowałem mój plan hostingowy, w którym mam teraz certyfikat SSL na moim hoście, który przechowuje pliki PHP i JS. Od czasu dodania certyfikatu SSL nie mam już tego problemu. Mam nadzieję, że to pomoże z tym dziwnym błędem.

Matthew Fallon
źródło
0

Napotkałem również ten błąd i sądzę, że może być wiele przyczyn tego błędu. Mój był, ARR zaczynał mieć limit czasu.

W moim przypadku przeglądarka wysyła żądanie do strony zwrotnego serwera proxy, gdzie ustawiłem moje zasady przekierowania, i ta strona proxy ostatecznie żąda rzeczywistej strony. Teraz dla ogromnych danych zajęło to ponad 2 minuty 5 sekund, a limit czasu routingu żądań aplikacji dla mojego serwera został ustawiony na 2 minuty. Naprawiłem to, zwiększając limit czasu ARR, wykonując poniższe czynności: 1. Przejdź do IIS 2. Kliknij nazwę serwera 3. Kliknij opcję Żądanie routingu pamięci podręcznej aplikacji w środkowym okienku 4. Kliknij Ustawienia serwera proxy w prawym okienku 5. Zwiększ limit czasu 6 Kliknij przycisk Zastosuj

Ankit
źródło
0

W naszym przypadku przyczyną był nieprawidłowy nagłówek. Jak wspomniano w Edycji 4:

  • weź dzienniki
  • w przeglądarce wybierz Zdarzenia
  • wybierz HTTP2_SESSION

Poszukaj czegoś podobnego:

HTTP2_SESSION_RECV_INVALID_HEADER

-> error = "Niepoprawny znak w nazwie nagłówka."

-> header_name = " charset = utf-8 "

Милан Енев
źródło
0

Mój zespół widział to w jednym pliku javascript, który serwowaliśmy. Każdy inny plik działał dobrze. Zmieniliśmy od http2tyłu do http1.1, a następnie albo net::ERR_INCOMPLETE_CHUNKED_ENCODINGalbo ERR_CONTENT_LENGTH_MISMATCH. Ostatecznie odkryliśmy, że istnieje filtr korporacyjny (Trustwave), który błędnie wykrywa „infolekcję” (podejrzewamy, że wykrył coś w naszym pliku / nazwie pliku, które przypominało numer ubezpieczenia społecznego). Zmodyfikowanie tego rozwiązania rozwiązało problem korporacyjny.

adamdport
źródło
0

Ten problem występował na stronach z długimi ciągami Base64. Problem występuje, ponieważ korzystamy z CloudFlare.

Szczegóły: https://community.cloudflare.com/t/err-http2-protocol-error/119619 .

Kluczowa sekcja z postu na forum:

Po dalszych testach na kartach Incognito w wielu przeglądarkach, a następnie wprowadzeniu zmian w kodzie z BASE64 do prawdziwego obrazu .png, problem nigdy się nie powtórzył w ŻADNEJ przeglądarce. Plik .png miał około 500 KB, zanim stał się base64, więc CloudFlare ma problemy z dużymi liniami tekstu w tej samej linii (ponieważ base64 jest długim łańcuchem) jako proxy między domeną a heroku. Jak wspomniano wcześniej, bezpośrednie trafienie na adres Heroku również nigdy nie miało miejsca.

Tymczasowy hack polega na wyłączeniu HTTP / 2 na CloudFlare.

Mam nadzieję, że ktoś inny może stworzyć lepsze rozwiązanie, które nie wymaga wyłączenia HTTP / 2 w CloudFlare.

Crashalot
źródło