Mam stronę, która pozwala użytkownikowi pobrać plik generowany dynamicznie. Generowanie zajmuje dużo czasu, więc chciałbym pokazać wskaźnik „czekania”. Problem polega na tym, że nie mogę ustalić, jak wykryć, kiedy przeglądarka otrzyma plik, więc mogę ukryć wskaźnik.
Zgłaszam żądanie w ukrytej formie, które POST wysyła do serwera i kieruje wyniki do ukrytej ramki iframe. Dzieje się tak, dlatego nie zastępuję całego okna przeglądarki wynikiem. Słucham zdarzenia „load” w ramce iframe, w nadziei, że zadziała po zakończeniu pobierania.
Z plikiem zwracam nagłówek „Content-Disposition: załącznik”, co powoduje, że przeglądarka wyświetla okno dialogowe „Zapisz”. Ale przeglądarka nie uruchamia zdarzenia „load” w ramce iframe.
Jednym ze sposobów, które wypróbowałem, jest użycie odpowiedzi wieloczęściowej. Wyśle więc pusty plik HTML, a także załączony plik do pobrania. Na przykład:
Content-type: multipart/x-mixed-replace;boundary="abcde"
--abcde
Content-type: text/html
--abcde
Content-type: application/vnd.fdf
Content-Disposition: attachment; filename=foo.fdf
file-content
--abcde
Działa to w przeglądarce Firefox; otrzymuje pusty plik HTML, uruchamia zdarzenie „ładuj”, a następnie wyświetla okno dialogowe „Zapisz” dla pliku do pobrania. Ale zawodzi w IE i Safari; IE uruchamia zdarzenie „ładuj”, ale nie pobiera pliku, a Safari pobiera plik (z niewłaściwą nazwą i typem zawartości) i nie uruchamia zdarzenia „ładuj”.
Innym podejściem może być wywołanie w celu rozpoczęcia tworzenia pliku, następnie odpytanie serwera, aż będzie on gotowy, a następnie pobranie już utworzonego pliku. Ale wolałbym unikać tworzenia plików tymczasowych na serwerze.
Czy ktoś ma lepszy pomysł?