SecureJPK
Zaloguj się

Limit rozmiaru i transmisja

Limit 100 MB i 250 MB JPK: jak wysłać duży plik XML na bramkę MF

Objaw / komunikat błędu

Przekroczono dopuszczalny rozmiar pliku (100 MB / 250 MB) albo przeglądarka zgłasza Out of Memory przy file.text() / DOMParser.

Programy księgowe i proste klienty webowe wczytują cały JPK do pamięci, zanim zaczną kompresję i szyfrowanie. Przy JPK_KR_PD, JPK_FA, JPK_MAG albo JPK_V7M powyżej stu megabajtów kończy się to zawieszeniem procesu albo twardym limitem rozmiaru.

Przyczyna techniczna

  • Wywołanie file.text() albo DOMParser.parseFromString() materializuje cały dokument jako jeden ciąg znaków UTF-16. Plik 400 MB na dysku potrafi zająć ponad gigabajt sterty, bo każdy znak to dwa bajty, a drzewo DOM dokłada wskaźniki węzłów.
  • Klasyczny ZIP (DEFLATE) budowany w pamięci trzyma słownik i bufor wyjścia obok oryginału. Dopiero potem AES dostaje kolejną kopię. Trzy równoległe obrazy tego samego XML-a przekraczają limit karty procesu w przeglądarce i w wielu klientach ERP.
  • Bramka e-Dokumenty nie przyjmuje jednego gigabajtowego blobu. Specyfikacja InitUpload dzieli zaszyfrowany strumień na paczki. W SecureJPK domyślny rozmiar paczki wyjściowej to 60 MiB (60 × 1024 × 1024), a odczyt oryginału idzie po 1 MiB.
  • Azure SAS bramki MF wymaga nagłówka x-ms-blob-type: BlockBlob. Bez niego PUT paczki kończy się HTTP 400, nawet gdy sam kryptogram jest poprawny.

Jak naprawić błąd krok po kroku

  1. 1

    Nie otwieraj dużego XML w edytorze ani w DOM

    Notatnik, przeglądarkowe podglądy i DOMParser nie są narzędziem do JPK_KR_PD liczącego setki megabajtów. Zostaw plik na dysku i podaj go strumieniowi, który czyta kolejne okna bajtów.

  2. 2

    Kompresuj i szyfruj w locie

    Strumień surowy wchodzi do ZipDeflate (fflate), a skompresowane bajty od razu do AES-256-CBC. Oryginał nie jest trzymany w całości obok wyniku. Klucz AES i IV powstają w przeglądarce i nie wracają na serwer aplikacji.

  3. 3

    Tnij kryptogram na paczki 60 MiB

    EncryptedOutputChunker zamyka paczkę po 60 × 1024 × 1024 bajtach wyjścia. Każda paczka dostaje własny MD5 Base64 (FileSignature) i idzie PUT-em jako BlockBlob na adres SAS zwrócony przez InitUploadSigned.

  4. 4

    Domknij sesję FinishUpload i dopiero wtedy pytaj o status

    Po ostatniej paczce przeglądarka woła FinishUpload. Bramka zaczyna składać ZIP i sprawdzać skróty. Dopiero kod 200 w Status zwraca UPO. Kody 1xx oznaczają, że duży plik jest jeszcze przetwarzany.

Jak rozwiązuje to architektura SecureJPK

Worker szyfrujący czyta plik jako strumień bajtów (1 MiB na odczyt), kompresuje go ZipDeflate i szyfruje AES-256-CBC bez budowania DOM. Wynik jest krojony na paczki 60 MiB i wysyłany wprost na Azure SAS bramki MF. Jawny XML nie trafia na serwer SecureJPK: to Strict Zero-Knowledge. Zakładka „Przygotuj plik” dodatkowo ogląda nagłówek strumieniem TextDecoderStream i zapisuje wynik w OPFS przez createSyncAccessHandle, więc walidacja wielogigabajtowego JPK nie ładuje go do RAM.

Najczęstsze pytania (FAQ)

Czy limit 100 MB jest limitem bramki MF?
Nie. To zwykle limit programu księgowego albo klienta, który trzyma cały XML w pamięci. Bramka przyjmuje sesję podzieloną na zaszyfrowane paczki, o ile InitUpload opisuje oryginalny rozmiar i skróty zgodnie ze schematem.
Dlaczego paczka ma 60 MiB, a nie 100 MB z cennika programu?
60 × 1024 × 1024 to rozmiar zaszyfrowanego wyjścia jednej paczki w workerze, nie limit pliku źródłowego. Plik źródłowy może mieć wiele takich paczek. Limit pakietu SecureJPK (250 MB, 2,5 GB albo brak limitu) dotyczy oryginału XML przed ZIP i AES.
Czy serwer SecureJPK widzi treść dużego JPK?
Nie. Serwer jest proxy CORS do API MF i strażnikiem subskrypcji na produkcji. Paczki .enc idą z przeglądarki na SAS. Operator nie dostaje jawnego XML ani klucza AES.