Błąd internetu

Błąd ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN – przyczyny i naprawa

Mateusz Sobociński
Autor: Mateusz Sobociński - CEO & Red. Nacz. @ asMAX
18 min. czytania
  1. Wprowadzenie
  2. Co to jest błąd ERRRESPONSEBODYTOOBIGTODRAIN?
  3. Przyczyny występowania błędu
  4. Rozwiązania dla użytkowników końcowych
  5. Rozwiązania dla webmasterów i deweloperów
  6. Prewencja i najlepsze praktyki
  7. Narzędzia diagnostyczne
  8. FAQ – Najczęściej zadawane pytania

1. Wprowadzenie

Błąd ERRRESPONSEBODYTOOBIGTODRAIN to stosunkowo rzadki, ale frustrujący problem, który może pojawić się podczas przeglądania stron internetowych. Ten poradnik zawiera kompleksowe informacje zarówno dla użytkowników końcowych, jak i profesjonalistów zajmujących się tworzeniem i zarządzaniem stronami internetowymi.

Dla kogo jest ten poradnik?

  • Użytkownicy końcowi – osoby napotykające ten błąd podczas przeglądania stron
  • Webmasterzy – administratorzy stron internetowych
  • Web deweloperzy – programiści tworzący aplikacje webowe
  • Administratorzy serwerów – osoby zarządzające infrastrukturą hostingową

2. Co to jest błąd ERRRESPONSEBODYTOOBIGTODRAIN?

Definicja techniczna

Błąd ERRRESPONSEBODYTOOBIGTODRAIN jest komunikatem zwracanym przez przeglądarkę (głównie Chrome i przeglądarki oparte na silniku Chromium) gdy:

  • Serwer próbuje wysłać zbyt dużą odpowiedź HTTP
  • Przeglądarka nie może przetworzyć całej treści odpowiedzi
  • Przekroczono limity buforowania danych w przeglądarce

Kiedy występuje?

Błąd pojawia się najczęściej w następujących sytuacjach:

  • Pobieranie dużych plików (wideo, obrazy w wysokiej rozdzielczości, archiwa)
  • Ładowanie stron z nadmiernymi zasobami (zbyt wiele skryptów, CSS, obrazków)
  • API zwracające ogromne zestawy danych (bez paginacji)
  • Przekierowania z dużą ilością danych w nagłówkach lub ciele odpowiedzi

Przykładowy wygląd błędu

Ten zasób nie może być wyświetlony ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN 

3. Przyczyny występowania błędu

3.1. Przyczyny po stronie serwera

Zbyt duże odpowiedzi API

// ZŁE - zwracanie całej bazy danych app.get('/api/users', (req, res) => { const allUsers = database.getAllUsers(); // 100,000+ rekordów res.json(allUsers); }); 

Nieoptymalizowane zasoby

  • Niewspompresowane obrazy (np. 20MB zdjęcia zamiast 200KB)
  • Zbyt duże pliki JavaScript/CSS bez minifikacji
  • Brak kompresji gzip/brotli na serwerze

Błędna konfiguracja serwera

  • Niewłaściwe limity rozmiaru odpowiedzi
  • Brak mechanizmów streaming dla dużych plików
  • Nieprawidłowe nagłówki HTTP

3.2. Przyczyny po stronie przeglądarki

Limity pamięci

  • Przeglądarka ma ograniczoną ilość pamięci do buforowania
  • Zbyt wiele otwartych kart zużywających zasoby
  • Brak wystarczającej ilości RAM w systemie

Rozszerzenia przeglądarki

  • Blokery reklam modyfikujące zawartość
  • Rozszerzenia Security/Privacy ingerujące w ruch sieciowy
  • Konflikty między rozszerzeniami

3.3. Przyczyny związane z siecią

  • Niestabilne połączenie powodujące ponowne próby
  • Proxy lub VPN bufujące zbyt dużo danych
  • Firewalle korporacyjne skanujące cały ruch

4. Rozwiązania dla użytkowników końcowych

Metoda 1 – Podstawowe kroki rozwiązywania problemu

Krok 1 – Odśwież stronę

Windows/Linux: Ctrl + F5 (twarde odświeżenie) Mac: Cmd + Shift + R 

Dlaczego to pomaga – Czyści cache dla konkretnej strony i wymusza ponowne pobranie zasobów.

Krok 2 – Wyczyść cache przeglądarki

Google Chrome

  1. Otwórz ustawienia (trzy kropki → Ustawienia)
  2. Przejdź do: Prywatność i bezpieczeństwo
  3. Kliknij: „Wyczyść dane przeglądania”
  4. Wybierz zakres czasowy: „Cały czas”
  5. Zaznacz:
  • ✓ Pliki cookie i inne dane witryn
  • ✓ Obrazy i pliki w pamięci podręcznej
  1. Kliknij „Wyczyść dane”

Mozilla Firefox –

  1. Menu → Ustawienia → Prywatność i bezpieczeństwo
  2. Sekcja „Ciasteczka i dane witryn”
  3. Kliknij „Wyczyść dane”
  4. Zaznacz obie opcje
  5. Kliknij „Wyczyść”

Microsoft Edge

  1. Ustawienia → Prywatność, wyszukiwanie i usługi
  2. „Wyczyść dane przeglądania” → „Wybierz, co wyczyścić”
  3. Wybierz zakres i elementy do wyczyszczenia
  4. Kliknij „Wyczyść teraz”

Krok 3 – Wyłącz rozszerzenia

Tryb incognito/prywatny –

Chrome: Ctrl + Shift + N (Windows) / Cmd + Shift + N (Mac) Firefox: Ctrl + Shift + P (Windows) / Cmd + Shift + P (Mac) Edge: Ctrl + Shift + N 

Sprawdzenie konkretnych rozszerzeń

  1. Otwórz: chrome://extensions/ (w Chrome)
  2. Wyłącz wszystkie rozszerzenia
  3. Spróbuj ponownie załadować stronę
  4. Jeśli działa, włączaj rozszerzenia po kolei, aby znaleźć winowajcę

Metoda 2 – Zaawansowane rozwiązania

Rozwiązanie A – Zmiana ustawień DNS

Windows –

  1. Panel sterowania → Sieć i Internet → Centrum sieci
  2. Kliknij na aktywne połączenie
  3. Właściwości → Internet Protocol Version 4 (TCP/IPv4)
  4. „Użyj następujących adresów serwerów DNS”:
  • Preferowany: 8.8.8.8 (Google DNS)
  • Alternatywny: 8.8.4.4
  1. OK → Zamknij

macOS

  1. Preferencje systemowe → Sieć
  2. Wybierz aktywne połączenie → Zaawansowane
  3. Zakładka DNS
  4. Kliknij + i dodaj: 8.8.8.8 i 8.8.4.4
  5. OK → Zastosuj

Linux (Ubuntu/Debian) –

# Edytuj plik konfiguracyjny sudo nano /etc/resolv.conf # Dodaj lub zmień na: nameserver 8.8.8.8 nameserver 8.8.4.4 # Zapisz (Ctrl+X, Y, Enter) 

Rozwiązanie B – Zmiana przeglądarki

Jeśli problem występuje tylko w jednej przeglądarce, spróbuj:

  • Chrome → przejdź na Firefox
  • Edge → przejdź na Chrome lub Opera
  • Przetestuj Brave (oparty na Chromium, ale z innymi ustawieniami)

Rozwiązanie C – Aktualizacja przeglądarki

Automatyczna aktualizacja Chrome

  1. Menu → Pomoc → Google Chrome — informacje
  2. Przeglądarka automatycznie sprawdzi aktualizacje
  3. Uruchom ponownie po zakończeniu

Sprawdzenie wersji –

  • Chrome: chrome://version/
  • Firefox: about:support
  • Edge: edge://version/

Metoda 3 – Optymalizacja systemu

Zwiększ dostępną pamięć RAM

Zamknij niepotrzebne aplikacje

Windows: Ctrl + Shift + Esc (Menedżer zadań) Mac: Cmd + Spacja → wpisz "Monitor aktywności" Linux: System Monitor lub htop w terminalu 

Zamknij procesy zużywające dużo pamięci, które nie są potrzebne.

Wyłącz akcelerację sprzętową

Chrome/Edge –

  1. Ustawienia → System
  2. Wyłącz: „Użyj akceleracji sprzętowej, gdy jest dostępna”
  3. Uruchom przeglądarkę ponownie

Firefox

  1. Ustawienia → Ogólne → Wydajność
  2. Odznacz: „Używaj zalecanych ustawień wydajności”
  3. Odznacz: „Użyj akceleracji sprzętowej, gdy jest dostępna”

5. Rozwiązania dla webmasterów i deweloperów

5.1. Diagnoza problemu

Narzędzia do monitorowania

Chrome DevTools –

// Otwórz DevTools: F12 lub Ctrl+Shift+I // Zakładka Network: // - Sprawdź rozmiar odpowiedzi (Size) // - Zobacz czas ładowania (Time) // - Zidentyfikuj duże zasoby (Size, Type) 

Analiza nagłówków

# Sprawdź nagłówki odpowiedzi curl -I https://twoja-strona.pl/duzy-plik.jpg # Szczegółowa analiza curl -v https://twoja-strona.pl/api/endpoint 2>&1 | grep -i "content-length" 

Skrypt diagnostyczny –

// Monitorowanie rozmiaru odpowiedzi w konsoli const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.transferSize > 10000000) { // > 10MB console.warn(`Duża odpowiedź: ${entry.name}`); console.warn(`Rozmiar: ${(entry.transferSize / 1024 / 1024).toFixed(2)} MB`); } } }); observer.observe({ entryTypes: ['resource'] }); 

5.2. Optymalizacja zasobów

A. Kompresja obrazów

Narzędzia i techniki

# ImageMagick - konwersja i kompresja convert duzy-obraz.jpg -quality 85 -resize 1920x1080 optymalizowany.jpg # Optipng dla PNG optipng -o7 obraz.png # WebP format (lepsza kompresja) cwebp -q 80 input.jpg -o output.webp 

Implementacja responsive images –

<picture> <source srcset="obraz-small.webp 480w, obraz-medium.webp 768w, obraz-large.webp 1200w" type="image/webp"> <source srcset="obraz-small.jpg 480w, obraz-medium.jpg 768w, obraz-large.jpg 1200w" type="image/jpeg"> <img src="obraz-medium.jpg" alt="Opis obrazu" loading="lazy"> </picture> 

B. Minifikacja i bundling

JavaScript

// webpack.config.js const TerserPlugin = require('terser-webpack-plugin'); module.exports = { optimization: { minimize: true, minimizer: [new TerserPlugin({ terserOptions: { compress: { drop_console: true, drop_debugger: true } } })], splitChunks: { chunks: 'all', maxSize: 244000, // ~244KB chunks } } }; 

CSS –

// PostCSS + cssnano module.exports = { plugins: [ require('cssnano')({ preset: ['default', { discardComments: { removeAll: true }, normalizeWhitespace: true }] }) ] }; 

C. Lazy loading

Obrazy

<!-- Native lazy loading --> <img src="obraz.jpg" loading="lazy" alt="Opis"> <!-- Intersection Observer API --> <script> document.addEventListener("DOMContentLoaded", function() { const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.remove('lazy'); observer.unobserve(img); } }); }); document.querySelectorAll('img.lazy').forEach(img => { imageObserver.observe(img); }); }); </script> 

Moduły JavaScript –

// Dynamic imports button.addEventListener('click', async () => { const module = await import('./duzy-modul.js'); module.inicjalizuj(); }); // React lazy loading const DuzyKomponent = React.lazy(() => import('./DuzyKomponent')); function App() { return ( <Suspense fallback={<div>Ładowanie...</div>}> <DuzyKomponent /> </Suspense> ); } 

5.3. Konfiguracja serwera

A. Kompresja gzip/brotli

Apache (.htaccess)

# Włącz mod_deflate <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript AddOutputFilterByType DEFLATE application/json application/xml application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml application/atom+xml AddOutputFilterByType DEFLATE image/svg+xml # Exclude już skompresowane formaty SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|gz|rar)$ no-gzip dont-vary </IfModule> # Brotli (jeśli dostępne) <IfModule mod_brotli.c> AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css AddOutputFilterByType BROTLI_COMPRESS text/javascript application/javascript application/json </IfModule> 

Nginx –

# nginx.conf http { # Gzip gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/atom+xml image/svg+xml; # Brotli brotli on; brotli_comp_level 6; brotli_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml; } 

Node.js (Express)

const compression = require('compression'); const express = require('express'); const app = express(); // Middleware kompresji app.use(compression({ level: 6, threshold: 1024, // Tylko dla plików > 1KB filter: (req, res) => { if (req.headers['x-no-compression']) { return false; } return compression.filter(req, res); } })); 

B. Content Delivery Network (CDN)

Konfiguracja Cloudflare –

// Cloudflare Workers - optymalizacja addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { const url = new URL(request.url); // Auto-minify dla zasobów statycznych const response = await fetch(request); if (response.headers.get('content-type')?.includes('text/html')) { // Włącz Auto Minify w panelu Cloudflare: // Speed → Optimization → Auto Minify } return response; } 

Cloudflare Page Rules

  1. Zaloguj się do Cloudflare
  2. Wybierz domenę → Page Rules
  3. Dodaj regułę dla *.js, *.css:
  • Cache Level: Cache Everything
  • Edge Cache TTL: 1 month
  1. Dla obrazów:
  • Polish: Lossless lub Lossy
  • Mirage: ON (lazy loading)

C. Streaming dla dużych plików

Node.js –

const fs = require('fs'); const path = require('path'); app.get('/download/duzy-plik', (req, res) => { const filePath = path.join(__dirname, 'files', 'duzy-plik.zip'); const stat = fs.statSync(filePath); res.writeHead(200, { 'Content-Type': 'application/zip', 'Content-Length': stat.size, 'Content-Disposition': 'attachment; filename=duzy-plik.zip' }); // Stream zamiast res.sendFile() const readStream = fs.createReadStream(filePath); readStream.pipe(res); readStream.on('error', (err) => { res.status(500).send('Błąd podczas pobierania'); }); }); 

PHP

<?php function streamFile($filePath) { if (!file_exists($filePath)) { http_response_code(404); die('Plik nie istnieje'); } $fileSize = filesize($filePath); $fileName = basename($filePath); header('Content-Type: application/octet-stream'); header('Content-Length: ' . $fileSize); header('Content-Disposition: attachment; filename="' . $fileName . '"'); header('Accept-Ranges: bytes'); // Stream w fragmentach 8KB $handle = fopen($filePath, 'rb'); while (!feof($handle)) { echo fread($handle, 8192); flush(); ob_flush(); } fclose($handle); } streamFile('/path/to/duzy-plik.zip'); ?> 

5.4. Paginacja i limitowanie danych

API REST – przykłady implementacji

Node.js + Express + MongoDB –

app.get('/api/users', async (req, res) => { try { // Parsowanie parametrów const page = parseInt(req.query.page) || 1; const limit = parseInt(req.query.limit) || 20; const skip = (page - 1) * limit; // Zabezpieczenie przed zbyt dużym limitem if (limit > 100) { return res.status(400).json({ error: 'Maksymalny limit to 100 rekordów' }); } // Query z paginacją const users = await User.find() .select('-password') // Exclude sensitive data .limit(limit) .skip(skip) .sort({ createdAt: -1 }); const total = await User.countDocuments(); res.json({ data: users, pagination: { currentPage: page, totalPages: Math.ceil(total / limit), totalItems: total, itemsPerPage: limit, hasNextPage: skip + limit < total, hasPrevPage: page > 1 } }); } catch (error) { res.status(500).json({ error: 'Błąd serwera' }); } }); 

PHP + MySQL

<?php function getPaginatedData($conn, $page = 1, $limit = 20) { // Walidacja $page = max(1, intval($page)); $limit = min(100, max(1, intval($limit))); // Max 100 $offset = ($page - 1) * $limit; // Zapytanie z limitami $stmt = $conn->prepare(" SELECT id, name, email, created_at FROM users ORDER BY created_at DESC LIMIT ? OFFSET ? "); $stmt->bind_param("ii", $limit, $offset); $stmt->execute(); $result = $stmt->get_result(); $data = $result->fetch_all(MYSQLI_ASSOC); // Liczba wszystkich rekordów $countStmt = $conn->prepare("SELECT COUNT(*) as total FROM users"); $countStmt->execute(); $totalResult = $countStmt->get_result(); $total = $totalResult->fetch_assoc()['total']; return [ 'data' => $data, 'pagination' => [ 'current_page' => $page, 'total_pages' => ceil($total / $limit), 'total_items' => $total, 'items_per_page' => $limit ] ]; } header('Content-Type: application/json'); echo json_encode(getPaginatedData( $conn, $_GET['page'] ?? 1, $_GET['limit'] ?? 20 )); ?> 

Python + Django REST Framework –

from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response class CustomPagination(PageNumberPagination): page_size = 20 page_size_query_param = 'limit' max_page_size = 100 def get_paginated_response(self, data): return Response({ 'data': data, 'pagination': { 'current_page': self.page.number, 'total_pages': self.page.paginator.num_pages, 'total_items': self.page.paginator.count, 'items_per_page': self.page_size, 'next': self.get_next_link(), 'previous': self.get_previous_link() } }) # W views.py from rest_framework import viewsets class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer pagination_class = CustomPagination 

Cursor-based pagination (dla dużych zbiorów)

Implementacja w Node.js

app.get('/api/posts', async (req, res) => { const limit = 20; const cursor = req.query.cursor; // ID ostatniego elementu let query = Post.find().limit(limit).sort({ _id: -1 }); if (cursor) { query = query.where('_id').lt(cursor); } const posts = await query.exec(); const nextCursor = posts.length === limit ? posts[posts.length - 1]._id : null; res.json({ data: posts, pagination: { nextCursor: nextCursor, hasMore: posts.length === limit } }); }); 

5.5. Monitoring i alerty

Implementacja logowania

Winston logger (Node.js) –

const winston = require('winston'); const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }) ] }); // Middleware do logowania dużych odpowiedzi app.use((req, res, next) => { const originalSend = res.send; res.send = function(data) { const size = Buffer.byteLength(JSON.stringify(data)); if (size > 5000000) { // > 5MB logger.warn({ message: 'Large response detected', endpoint: req.path, size: size, timestamp: new Date().toISOString() }); } originalSend.call(this, data); }; next(); }); 

Google Analytics – śledzenie błędów

// Śledzenie błędów w GA4 window.addEventListener('error', (event) => { if (window.gtag) { gtag('event', 'exception', { description: event.error.message, fatal: false }); } }); // Monitorowanie performance window.addEventListener('load', () => { const perfData = window.performance.timing; const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart; if (pageLoadTime > 5000 && window.gtag) { // > 5s gtag('event', 'slow_page_load', { event_category: 'Performance', event_label: window.location.pathname, value: Math.round(pageLoadTime) }); } }); 

Sentry – monitoring błędów

// Instalacja: npm install @sentry/browser import * as Sentry from "@sentry/browser"; Sentry.init({ dsn: "YOUR_SENTRY_DSN", integrations: [new Sentry.BrowserTracing()], tracesSampleRate: 1.0, beforeSend(event, hint) { // Dodaj informacje o dużych requestach if (hint.originalException instanceof Error) { if (hint.originalException.message.includes('TOO_BIG')) { event.tags = event.tags || {}; event.tags.error_type = 'large_response'; } } return event; } }); 

6. Prewencja i najlepsze praktyki

6.1. Checklist dla deweloperów

✅ Przed wdrożeniem na produkcję

Optymalizacja zasobów

  • [ ] Wszystkie obrazy są skompresowane (max 200KB dla większości)
  • [ ] Format WebP jest dostępny jako alternatywa
  • [ ] JavaScript i CSS są zminifikowane
  • [ ] Nieużywany kod został usunięty (tree-shaking)
  • [ ] Critical CSS jest inline w <head>
  • [ ] Fonty są ładowane z font-display: swap

API i dane –

  • [ ] Wszystkie endpointy mają paginację
  • [ ] Maksymalny rozmiar odpowiedzi to 1MB
  • [ ] Długie listy używają virtual scrolling
  • [ ] Implementacja rate limiting
  • [ ] GraphQL queries mają depth limiting

Serwer

  • [ ] Włączona kompresja gzip/brotli
  • [ ] Ustawione odpowiednie cache headers
  • [ ] CDN jest skonfigurowany
  • [ ] Monitoring czasu odpowiedzi
  • [ ] Load balancing dla dużego ruchu

Performance Budget –

// performance-budget.json { "budgets": [ { "resourceSizes": [ { "resourceType": "script", "budget": 300 }, { "resourceType": "image", "budget": 500 }, { "resourceType": "stylesheet", "budget": 100 }, { "resourceType": "total", "budget": 1000 } ] } ] } 

6.2. Architektura aplikacji

Mikroserwisy vs Monolit

Zalety mikroserwisów – „`javascript // Serwis A – obsługa użytkowników (mały payload) app.get(’/api/users/:id’, async (req, res) => { const user = await UserService.getById(req.params.id); res.json({ user }); // ~2KB });

// Serwis B – obsługa obrazów (duży payload) app.get(’/api/images/:

Podziel się artykułem
CEO & Red. Nacz. @ asMAX
Obserwuj:
Ex-redaktor w GW (Technologie) i ex-PR w koreańskim start-upie technologicznym. Absolwent Imperial College Business School (MBA) i Politechniki Warszawskiej. Od 2025 CEO i redaktor naczelny w asMAX.
Brak komentarzy

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *