Что такое net :: ERR_HTTP2_PROTOCOL_ERROR?

36

В настоящее время я работаю над сайтом, который вызывает net::ERR_HTTP2_PROTOCOL_ERROR 200ошибку в Google Chrome. Я не уверен, что именно может спровоцировать эту ошибку, я только заметил, что она выскакивает только при доступе к сайту в HTTPS. Я не могу быть на 100% уверен, что это связано, но похоже, что это препятствует правильному выполнению JavaScript.

Например, следующий сценарий происходит:

  1. Я захожу на сайт в HTTPS

  2. Мой канал Twitter, интегрированный через https://publish.twitter.com, вообще не загружается

  3. Я могу заметить в консоли ERR_HTTP2_PROTOCOL_ERROR

  4. Если я удаляю код для загрузки канала Twitter, ошибка остается

  5. Если я захожу на сайт по HTTP, появляется канал Twitter и ошибка исчезает

Google Chrome - единственный веб-браузер, вызывающий ошибку: он хорошо работает как в Edge, так и в Firefox. (NB: я пробовал с Safari, и у меня похожая kcferrordomaincfnetwork 303ошибка)

Мне было интересно, может ли это быть связано с заголовком, возвращаемым сервером, так как в ошибке есть упоминание «200», а страница 404/500 ничего не вызывает.

Дело в том, что ошибка не документирована вообще. Поиск в Google дает мне очень мало результатов. Более того, я заметил, что это появляется в самых последних выпусках Google Chrome; ошибка не появляется на v.64.X, но на v.75 + (независимо от ОС; я работаю на Mac tho).

Любая подсказка на данный момент для расследования будет с благодарностью!

Заранее спасибо.

Тристан


Изменить 1: Может быть связано с веб-сайта в порядке в Firefox, но не в Safari (kCFErrorDomainCFNetwork ошибка 303), ни Chrome (net :: ERR_SPDY_PROTOCOL_ERROR)


Изменить 2: Результаты дальнейших исследований следующие:

  • ошибка не появляется на той же самой странице, если сервер возвращает 404 вместо 2XX
  • ошибка не появляется на локальном с сертификатом HTTPS
  • ошибка появляется на другом сервере (оба OVH), который использует другой сертификат
  • ошибка появляется независимо от того, какая версия PHP используется, от 5.6 до 7.3 (используемая среда: Cakephp 2.10)

Редактировать 3: В соответствии с запросом ниже приводится возвращаемый заголовок для ресурса, на котором произошел сбой, - это целая веб-страница. Даже если ошибка запускается на каждой странице, имеющей HTTP-заголовок 200, эти страницы всегда загружаются в браузер клиента, но иногда отсутствует элемент (в моем примере - внешний канал Twitter). Все остальные активы на вкладке «Сеть» имеют успешный возврат, кроме самого документа. линия, которая потерпела неудачу в консоли

Заголовок Google Chrome (с ошибкой):

Chrome header

Заголовок Firefox (без ошибок):

Firefox header

curl --head --http2Запрос в консоли возвращает следующий успех:

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

Изменить 4: Попытка углубиться в инструменты chrome: // net-export / и https://netlog-viewer.appspot.com говорит мне, что запрос заканчивается RST_STREAM:

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

Что я прочитал в этом другом посте : « В HTTP / 2, если клиент хочет прервать запрос, он отправляет RST_STREAM. Когда сервер получает RST_STREAM, он прекращает отправку кадров DATA клиенту, тем самым останавливая ответ (или загрузка). Соединение все еще может использоваться для других запросов, и запросы / ответы, которые были параллельны тому, который был прерван, могут продолжать прогрессировать. [...] Возможно, что к тому времени, когда RST_STREAM отправится из клиент на сервер, весь контент запроса находится в пути и прибудет к клиенту, который его отбросит, однако при большом содержании ответа отправка RST_STREAM может иметь хорошие шансы прибыть на сервер раньше, чем весь Содержание ответа отправляется, и, следовательно, будет экономить пропускную способность. "

Описанное поведение такое же, как и то, что я могу наблюдать. Но это будет означать, что виновником является браузер, и тогда я не пойму, почему это происходит на двух идентичных страницах, одна из которых имеет заголовок 200, а другая 404 (то же самое происходит, если я отключаю JS).

Тристан Г
источник
aboutssl.org/fix-google-chrome-error-err_ssl_protocol_error это один из 110 результатов -
Jaromanda X
Я был здесь, очевидно, и есть только ответы на стороне клиента, которые не могут быть решением.
Тристан G
ошибка возникает в браузерах без Chrome? если нет, то как это не проблема на стороне клиента (особенно браузера Chrum)?
Jaromanda X
1
Вероятно, неправильно сформированные заголовки ответа HTTP. Весь сайт не загружается? Или только один или несколько активов? Можете ли вы отредактировать вопрос, включив заголовки ответов HTTP, показанные в ответе http, для ресурса, который не загружается при использовании HTTP / 2? А также для Edge / Firefox, где это работает?
Барри Поллард
1
Там не вижу ничего плохого, поэтому подозреваю, что это не главная просьба. Также не обращайте внимания на вещь, связанную с печеньем - это не так. Попробуйте, чтобы увидеть, можете ли вы понять это: michalspacek.com/…
Барри Поллард,

Ответы:

7

В течение нескольких недель меня тоже раздражала эта «ошибка»:

net :: ERR_HTTP2_PROTOCOL_ERROR 200

В моем случае это произошло на изображениях, сгенерированных PHP.

Это было на header()уровне, и на этом в частности:

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

Он явно не вернул точный размер, поэтому я удалил его, и теперь все работает нормально.

Таким образом, Chrome проверяет точность данных, передаваемых через заголовки, и, если они не совпадают, происходит сбой.

РЕДАКТИРОВАТЬ

Я обнаружил, почему content-lengthvia filesizeнеправильно рассчитывается: GZIPсжатие активно для файлов PHP, поэтому исключение рассматриваемого файла решит проблему. Поместите этот код в .htaccess:

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

Это работает, и мы держим заголовок Content-length.

Xtendo
источник
1
Отлично, ты спас меня !!! Но я до сих пор не понимаю реальной проблемы, в моем случае ошибка происходит только в https, но не в http.
Нико
Здравствуйте @Nico, да, я думаю, что это нормально, проверка между объявленным размером и размером файла, загруженного браузером (Chrome), должна выполняться только по протоколу https. Очень рад, что это решение может помочь вам!
Xtendo
1
Каким-то образом мне удалось использовать «Content -Length» вместо «Content-Length». После удаления пробела все заработало. Спасибо.
Мартин Лоттеринг
Здравствуйте @Martin Lottering Очень рад, что теперь это работает для вас! :-)
Xtendo
6

Я не понял, что именно происходит, но я нашел решение.

Особенностью CDN OVH был виновник. Он был установлен на моей хост-службе, но отключен для моего домена, потому что он мне не нужен.

Почему-то, когда я его включаю, все работает.

Я думаю, что это заставляет Apache использовать протокол HTTP2, но я не понимаю, что в каждом из моих заголовков действительно было упоминание HTTP2, что, как я предполагаю, означает, что сервер отвечал, используя правильный протокол.

Таким образом, решение для моего очень конкретного случая состояло в том, чтобы включить опцию CDN во всех соответствующих доменах.

Если кто-то лучше понимает, что здесь могло случиться, не стесняйтесь делиться объяснениями.

Тристан Г
источник
очистка кэша cdn работала для меня
Varshaan
4

Я столкнулся с этим, потому что сервер http2 закрыл соединение при отправке большого ответа на Chrome.

Почему? Потому что это просто настройка сервера http2 с именем WriteTimeout .

одна книга
источник
4

В моем случае это было - на веб-сервере не осталось места на диске.

Алекс Калмиков
источник
Интересно, для меня же, на переднем веб-сервере был полный диск. похоже, что nginx не улавливает эту ситуацию, потому что в журнале не было ничего заметного.
vchrizz
3

У меня возникла похожая проблема, я получал ERR_HTTP2_PROTOCOL_ERROR на один из запросов HTTP GET.

Я заметил, что обновление Chrome было отложено, поэтому я обновил браузер Chrome до последней версии, и ошибка исчезла в следующий раз, когда я перезапустил браузер.

Jaikumar
источник
2

У меня была эта проблема, когда у меня был сервер Nginx, который выставлял приложение node-js во внешний мир. Nginx сжал файл (css, js, ...) с gzipпомощью Chrome и выглядел так же.

Проблема была решена, когда мы обнаружили, что сервер node-js также сжимает содержимое с помощью gzip. В некотором роде это двойное сжатие приводит к этой проблеме. Отмена сжатия node-js решила проблему.

No1Lives4Ever
источник
6
Интересно видеть, что несколько человек уже ответили на этот пост, и каждый раз корень проблемы был чем-то другим. Я думаю, что эта ошибка действительно сбивает с толку.
Тристан G
2

Эта ошибка в настоящее время исправляется: https://chromium-review.googlesource.com/c/chromium/src/+/2001234

Но это помогло мне, изменив настройки nginx:

  • включение gzip;
  • add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age = 0';
  • истекает;

В моем случае Nginx действует как обратный прокси-сервер для приложения Node.js.

Эдуардса
источник
этот ответ работал и для меня. Перейдите по этой ссылке docs.nginx.com/nginx/admin-guide/web-server/compression для правильного синтаксиса
Бхаргави Гопалачар
1

Это случилось со мной, когда я зарегистрировал новое доменное имя, например, «new» для example.com (new.example.com). Имя не может быть разрешено временно в моем месте в течение пары часов, в то время как оно может быть решено за границей. Поэтому я использовал прокси-сервер для проверки веб-сайта, на котором я видел net::ERR_HTTP2_PROTOCOL_ERRORв консоли Chrome несколько сообщений AJAX. Несколько часов спустя, когда имя можно было восстановить локально, эти ошибки просто исчезли.

Я думаю, что причина этой ошибки в том, что запросы AJAX не были перенаправлены моим прокси-сервером, а просто посещают веб-сайт, который не был разрешен моим локальным DNS-распознавателем.

Dzhuang
источник
1

Я сталкивался с этой ошибкой несколько раз, и это было связано с передачей больших ресурсов (более 3 МБ) с сервера на клиент.

Ферейдун Барикзехи
источник
0

У меня возникла та же проблема (asp, c # - HttpPostedFileBase) при публикации файла размером более 1 МБ (даже если приложение не имеет каких-либо ограничений по размеру файла), мне помогло упрощение класса модели. Если у вас возникла эта проблема, попробуйте удалить некоторые части модели и посмотреть, поможет ли она в любом случае. Звучит странно, но у меня получилось.

LV
источник
0

Я столкнулся с этой проблемой в течение последней недели, так как пытался отправить запросы DELETE на мой PHP-сервер через AJAX. Я недавно обновил свой хостинг-план, теперь у меня есть SSL-сертификат на моем хосте, который хранит файлы PHP и JS. После добавления SSL-сертификата у меня больше нет этой проблемы. Надеюсь, что это помогает с этой странной ошибкой.

Мэтью Фэллон
источник
0

Я также столкнулся с этой ошибкой, и я полагаю, что может быть несколько причин. Мой был, ARR получал тайм-аут.

В моем случае браузер отправлял запрос на обратный прокси-сайт, где я установил правила перенаправления, и этот прокси-сайт в итоге запрашивает реальный сайт. Теперь для огромных данных это заняло более 2 минут 5 секунд, а для моего сервера время ожидания маршрутизации запросов было установлено равным 2 минутам. Я исправил это, увеличив время ожидания ARR, выполнив следующие шаги: 1. Перейдите в IIS 2. Нажмите на имя сервера 3. Нажмите на кэш маршрутизации запросов приложений в средней панели 4. Нажмите Параметры прокси-сервера на правой панели 5. Увеличьте время ожидания 6 Нажмите Применить

Анкит
источник
0

В нашем случае причиной стал неверный заголовок. Как упомянуто в Edit 4:

  • возьми логи
  • в окне просмотра выберите События
  • выбрал HTTP2_SESSION

Ищите что-то похожее:

HTTP2_SESSION_RECV_INVALID_HEADER

-> error = "Недопустимый символ в имени заголовка."

-> header_name = " charset = utf-8 "

Милан Енев
источник
0

Моя команда увидела это в одном файле javascript, который мы обслуживали. Все остальные файлы работали нормально. Мы перешли от http2обратно к, http1.1а затем либо net::ERR_INCOMPLETE_CHUNKED_ENCODINGили ERR_CONTENT_LENGTH_MISMATCH. В конечном итоге мы обнаружили, что существует корпоративный фильтр (Trustwave), который ошибочно обнаруживает «утечку информации» (мы подозреваем, что в нашем файле / имени файла обнаружилось что-то похожее на номер социального страхования). Корпоративная настройка этого фильтра решила наши проблемы.

adamdport
источник
0

Мы столкнулись с этой проблемой на страницах с длинными строками Base64. Проблема возникает потому, что мы используем CloudFlare.

Подробности: https://community.cloudflare.com/t/err-http2-protocol-error/119619 .

Ключевой раздел из поста форума:

После дальнейшего тестирования вкладок Incognito в нескольких браузерах, а затем внесения изменений в код с BASE64 в реальное изображение .png, эта проблема больше никогда не возникала в ЛЮБОМ браузере. У .png было около 500 КБ, прежде чем он стал base64, поэтому CloudFlare имеет проблемы с огромными строками текста на одной строке (поскольку base64 - длинная строка) в качестве прокси между доменом и герою. Как уже упоминалось ранее, прямого попадания по URL Heroku также никогда не возникало.

Временный взлом заключается в отключении HTTP / 2 на CloudFlare.

Надеюсь, что кто-то еще может предложить лучшее решение, которое не требует отключения HTTP / 2 на CloudFlare.

Crashalot
источник