Od czasu uaktualnienia do systemu iOS 6 widzimy, że widok przeglądarki Safari pozwala na buforowanie $.ajax
połączeń. Jest to w kontekście aplikacji PhoneGap, więc korzysta ona z Safari WebView. Nasze $.ajax
wywołania są POST
metodami, a pamięć podręczna ma wartość false {cache:false}
, ale tak się dzieje. Próbowaliśmy ręcznie dodać a TimeStamp
do nagłówków, ale to nie pomogło.
Zrobiliśmy więcej badań i stwierdziliśmy, że Safari zwraca wyniki z pamięci podręcznej tylko dla usług internetowych, które mają podpis funkcji, który jest statyczny i nie zmienia się z połączenia do połączenia. Na przykład wyobraź sobie funkcję o nazwie coś takiego:
getNewRecordID(intRecordType)
Ta funkcja odbiera ciągle te same parametry wejściowe, ale zwracane dane powinny za każdym razem być inne.
Musi być w pośpiechu Apple, aby imponujący zip w iOS 6 był zbyt zadowolony z ustawień pamięci podręcznej. Czy ktoś jeszcze widział takie zachowanie na iOS 6? Jeśli tak, co dokładnie to powoduje?
Obejściem tego problemu było zmodyfikowanie podpisu funkcji w taki sposób:
getNewRecordID(intRecordType, strTimestamp)
a następnie zawsze przekazuj również TimeStamp
parametr i po prostu odrzuć tę wartość po stronie serwera. Działa to wokół problemu. Mam nadzieję, że pomoże to innej biednej duszy, która spędza 15 godzin w tej sprawie, tak jak ja!
źródło
Odpowiedzi:
Po krótkiej analizie okazuje się, że Safari na iOS6 będzie buforować pliki POST, które nie mają nagłówków Cache-Control, a nawet „Cache-Control: max-age = 0”.
Jedynym sposobem, w jaki udało mi się zapobiec temu buforowaniu na poziomie globalnym, zamiast konieczności włamywania się do losowych zapytań na koniec zgłoszeń serwisowych, jest ustawienie „Kontrola pamięci podręcznej: brak pamięci podręcznej”.
Więc:
Podejrzewam, że Apple korzysta z tego na podstawie specyfikacji HTTP w sekcji 9.5 na temat POST:
Teoretycznie możesz buforować odpowiedzi POST ... kto wiedział. Ale jak dotąd żaden inny twórca przeglądarki nie pomyślał, że to dobry pomysł. Ale to NIE uwzględnia buforowania, gdy nie są ustawione nagłówki Kontroli pamięci podręcznej lub Wygasają, tylko jeśli są ustawione. To musi być błąd.
Poniżej znajduje się to, czego używam w odpowiednim fragmencie mojej konfiguracji Apache do kierowania na cały mój API, ponieważ tak się składa, że tak naprawdę nie chcę niczego buforować, nawet dostaje. Nie wiem, jak ustawić to tylko dla testów POST.
Aktualizacja: Właśnie zauważyłem, że nie zauważyłem, że dzieje się tak tylko wtedy, gdy POST jest taki sam, więc zmień dowolne dane lub adres URL POST i nic ci nie będzie. Możesz więc, jak wspomniano w innym miejscu, po prostu dodać losowe dane do adresu URL lub trochę danych POST.
Aktualizacja: Możesz ograniczyć „brak pamięci podręcznej” tylko do POST, jeśli chcesz tak w Apache:
źródło
Mam nadzieję, że może to być przydatne dla innych programistów walących głową o ścianę. Odkryłem, że którykolwiek z poniższych przypadków uniemożliwia przeglądarce Safari w systemie iOS 6 buforowanie odpowiedzi POST:
Moje rozwiązanie było następujące w moim Javascript (wszystkie moje żądania AJAX to POST).
Dodam również nagłówek [pragma: no-cache] do wielu moich odpowiedzi serwera.
Jeśli użyjesz powyższego rozwiązania, pamiętaj, że wszelkie wywołania $ .ajax (), które są ustawione na globalne: false NIE będą używać ustawień określonych w $ .ajaxSetup (), więc będziesz musiał ponownie dodać nagłówki.
źródło
Proste rozwiązanie dla wszystkich żądań usług sieciowych, przy założeniu, że używasz jQuery:
Przeczytaj więcej o wywołaniu filtra wstępnego jQuery tutaj .
Jeśli nie korzystasz z jQuery, sprawdź dokumenty w wybranej bibliotece. Mogą mieć podobną funkcjonalność.
źródło
Właśnie miałem ten problem w aplikacji PhoneGap . Rozwiązałem go za pomocą funkcji JavaScript
getTime()
w następujący sposób:Zmarnowałem kilka godzin, zastanawiając się nad tym. Byłoby miło, gdyby Apple powiadomił programistów o tym problemie z buforowaniem.
źródło
{cache:false}
jako opcji albo,$.post()
albo$.ajaxSetup()
, zgodnie z dokumentami , te argumenty są ignorowane; jQuery „nigdy nie buforuje” żądań wysyłania, ale nie bierze pod uwagę przeglądarki. Być może lepszym rozwiązaniem byłoby dodanie znacznika czasu do żądań za pomocą$.ajaxPrefilter()
.function send_ajax(my_data,refresh)
. patrz tutaj stackoverflow.com/questions/14733772/...Miałem ten sam problem z aplikacją internetową pobierającą dane z usługi ASP.NET
To działało dla mnie:
źródło
Wreszcie mam rozwiązanie mojego problemu z przesyłaniem.
W JavaScript:
W PHP :
źródło
Z mojego własnego posta na blogu iOS 6.0 buforuje żądania Ajax POST :
Jak to naprawić: Istnieją różne metody zapobiegania buforowaniu żądań. Zalecaną metodą jest dodanie nagłówka bez pamięci podręcznej. Tak to się robi.
jQuery:
Sprawdź iOS 6.0 i ustaw nagłówek Ajax w następujący sposób:
ZeptoJS:
Sprawdź system iOS 6.0 i ustaw nagłówek Ajax w następujący sposób:
Po stronie serwera
Jawa:
Pamiętaj, aby dodać to u góry strony, zanim jakiekolwiek dane zostaną wysłane do klienta.
.NETTO
Lub
PHP
źródło
Ten fragment kodu JavaScript działa doskonale w przypadku jQuery i jQuery Mobile:
Po prostu umieść go gdzieś w kodzie JavaScript (po załadowaniu jQuery, najlepiej przed zrobieniem żądań AJAX) i powinno to pomóc.
źródło
Możesz również rozwiązać ten problem, modyfikując funkcję Ajax jQuery , wykonując następujące czynności (od 1.7.1) na górze funkcji Ajax (funkcja zaczyna się od linii 7212). Ta zmiana aktywuje wbudowaną funkcję anty-cache jQuery dla wszystkich żądań POST.
(Pełny skrypt jest dostępny pod adresem
http://dl.dropbox.com/u/58016866/jquery-1.7.1.js
.)Wstaw poniżej wiersza 7221:
Następnie zmodyfikuj następujące elementy (od linii ~ 7497).
Do:
źródło
jQuery.ajaxPrefiler
, aby zmodyfikować zapytanie ajax bezpośrednio przed jego wykonaniem. Możesz zarchiwizować to samo z bardziej zoptymalizowanym i zaktualizować bezpieczny kod.Szybkim obejściem usług GWT-RPC jest dodanie tego do wszystkich metod zdalnych:
źródło
To jest aktualizacja odpowiedzi Baz1nga. Ponieważ
options.data
nie jest obiektem, ale ciągiem, po prostu uciekłem się do konkatenacji znacznika czasu:źródło
Aby rozwiązać ten problem dla aplikacji internetowych dodanych do ekranu głównego, należy przestrzegać obu najczęściej głosowanych obejść. Buforowanie musi być wyłączone na serwerze WWW, aby zapobiec buforowaniu nowych żądań w przyszłości, a do każdego żądania postu należy dodać losowe dane wejściowe, aby żądania, które już zostały buforowane, zostały zrealizowane. Proszę odnieść się do mojego postu:
iOS6 - Czy istnieje sposób na wyczyszczenie buforowanych żądań POST dla aplikacji WWW dodanych do ekranu głównego?
OSTRZEŻENIE: każdemu, kto zaimplementował obejście, dodając znacznik czasu do swoich żądań bez wyłączania buforowania na serwerze. Jeśli Twoja aplikacja zostanie dodana do ekranu głównego, KAŻDY post postu będzie teraz buforowany, wyczyszczenie pamięci podręcznej safari nie wyczyści jej i nie będzie wygasać. Chyba że ktoś ma sposób, aby to wyczyścić, wygląda to na potencjalny wyciek pamięci!
źródło
Rzeczy, które NIE DZIAŁAŁY dla mnie na iPadzie 4 / iOS 6:
Moja prośba zawiera: Cache-Control: no-cache
Dodanie bufora: false do mojego wywołania jQuery ajax
Tylko to załatwiło sprawę:
źródło
$.ajax
cache: false
Dołącza adres URL do parametru zapytania_=Date.prototype.getTime()
, więc ręczne dołączanie znacznika czasu nie powinno być dłużej potrzebne.To jest obejście GWT-RPC
źródło
Moje obejście w ASP.NET (pagemethods, webservice itp.)
źródło
Chociaż dodanie parametrów pomijania pamięci podręcznej, aby wyglądało inaczej, wydaje się solidnym rozwiązaniem, odradzam to, ponieważ zaszkodziłoby każdej aplikacji, która opiera się na faktycznym buforowaniu. Uczynienie wyjściowymi interfejsami API poprawnych nagłówków jest najlepszym możliwym rozwiązaniem, nawet jeśli jest to nieco trudniejsze niż dodawanie modułów blokujących pamięć podręczną do dzwoniących.
źródło
Dla tych, którzy używają
Struts 1
, oto jak naprawiłem problem.web.xml
com.example.struts.filters.CacheControlFilter.js
źródło
Byłem w stanie rozwiązać problem, używając kombinacji $ .ajaxSetup i dołączając znacznik czasu do adresu URL mojego postu (nie do parametrów / treści postu). Opiera się to na zaleceniach poprzednich odpowiedzi
źródło
Myślę, że rozwiązałeś już swój problem, ale pozwól, że podzielę się pomysłami na temat buforowania w sieci.
To prawda, że możesz dodać wiele nagłówków w każdym używanym języku, po stronie serwera, po stronie klienta i możesz użyć wielu innych sztuczek, aby uniknąć buforowania w sieci, ale zawsze myśl, że nigdy nie wiesz, skąd klient łączy się z twoim serwerem, nigdy nie wiadomo, czy korzysta on z hotelowego połączenia „Hot-Spot”, które wykorzystuje Squid lub inne produkty buforowania.
Jeśli użytkownicy używają proxy do ukrycia swojej prawdziwej pozycji itp.… Prawdziwej jedynym sposobem uniknięcia buforowania jest znacznik czasu w żądaniu, również jeśli nie jest używany.
Na przykład:
Następnie każdy menedżer pamięci podręcznej, który musisz przekazać, nie znalazł tego samego adresu URL w repozytorium pamięci podręcznej i ponownie pobierał zawartość strony.
źródło
$.ajax
i ustawisz opcje, aby{cache:false}
jQuery automatycznie dodało pomijanie pamięci podręcznej za kulisami, bez potrzeby robienia czegokolwiek innego.W zależności od aplikacji możesz teraz rozwiązać problem w iOS 6 za pomocą Safari> Zaawansowane> Inspektor sieci, więc jest to pomocne w tej sytuacji.
Podłącz telefon do Safari na komputerze Mac, a następnie użyj menu programisty, aby rozwiązać problemy z aplikacją internetową.
Wyczyść dane witryny na iPhonie po aktualizacji do iOS6, w tym dane specyficzne dla aplikacji za pomocą Widoku internetowego. Tylko jedna aplikacja miała problem i to rozwiązało go podczas testów IOS6 Beta w przeszłości, od tamtej pory nie było żadnych poważnych problemów.
Konieczne może być również spojrzenie na aplikację, sprawdź NSURLCache, jeśli w WebView w aplikacji niestandardowej.
https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003754
Myślę, że w zależności od prawdziwej natury twojego problemu, wdrożenia itp.
Ref: $ .ajax połączenia
źródło
Znalazłem jedno obejście, które mnie ciekawi, dlaczego to działa. Zanim przeczytałem odpowiedź Tadej'a dotyczącą serwisu internetowego ASP.NET, próbowałem wymyślić coś, co by działało.
I nie mówię, że to dobre rozwiązanie, ale chciałem to tutaj udokumentować.
strona główna: zawiera funkcję JavaScript, checkStatus (). Metoda wywołuje inną metodę, która używa wywołania AJAX jQuery do aktualizacji zawartości HTML. Użyłem setInterval do wywołania checkStatus (). Oczywiście napotkałem problem z buforowaniem.
Rozwiązanie: użyj innej strony, aby wywołać aktualizację.
Na stronie głównej ustawiłem zmienną boolowską, runUpdate, i dodałem następujące do tagu body:
W pliku helper.html:
Jeśli więc funkcja checkStatus () zostanie wywołana ze strony głównej, otrzymam buforowaną zawartość. Jeśli wywołam checkStatus ze strony podrzędnej, otrzymam zaktualizowaną treść.
źródło
Podczas gdy moje strony logowania i rejestracji działają jak urok w Firefox, IE i Chrome ... Walczyłem z tym problemem w Safari dla IOS i OSX, kilka miesięcy temu znalazłem obejście dla SO.
LUB przez javascript
To trochę brzydka rzecz, ale działa przez jakiś czas.
Nie wiem dlaczego, ale zwracając null do
onunload
zdarzenia, strona nie jest buforowana w Safari.źródło
Okazało się, że starsze iPhone'y i iPady z systemem iOS w wersji 9 i 10 czasami zwracają fałszywe, puste wyniki AJAX, być może z powodu zmniejszenia szybkości procesora przez Apple. Zwracając pusty wynik, iOS nie wywołuje serwera, tak jakby zwracał wynik z pamięci podręcznej. Częstotliwość różni się znacznie, od około 10% do 30% połączeń AJAX zwraca puste.
Trudno w to uwierzyć. Poczekaj 1s i zadzwoń ponownie. W naszych testach wystarczyło tylko jedno powtórzenie, ale napisaliśmy kod, aby wywołać go 4 razy. Nie jesteśmy pewni, czy oczekiwanie 1s jest wymagane, ale nie chcieliśmy ryzykować obciążeniem naszego serwera serią powtarzających się połączeń.
Odkryliśmy, że problem wystąpił w przypadku dwóch różnych wywołań AJAX, wywołujących różne pliki API z różnymi danymi. Ale obawiam się, że może się to zdarzyć przy każdym połączeniu AJAX. Po prostu nie wiemy, ponieważ nie sprawdzamy każdego wyniku AJAX i nie testujemy każdego połączenia wiele razy na starych urządzeniach.
Oba problematyczne wywołania AJAX używały: POST, Asynchronicznie = true, setRequestHeader = ('Content-Type', 'application / x-www-form-urlencoded')
Kiedy problem się pojawia, zwykle trwa tylko jedno wywołanie AJAX. Nie jest to spowodowane nakładającymi się połączeniami AJAX. Czasami problem występuje, gdy urządzenie jest zajęte, ale czasami nie, a bez DevTools tak naprawdę nie wiemy, co się dzieje w tym czasie.
iOS 13 tego nie robi, ani Chrome, ani Firefox. Nie mamy żadnych urządzeń testowych z systemem iOS 11 lub 12. Być może ktoś inny mógłby je przetestować?
Zwracam na to uwagę, ponieważ to pytanie jest najwyższym wynikiem Google podczas wyszukiwania tego problemu.
źródło
Działa z ASP.NET dopiero po dodaniu
pragma:no-cache
nagłówka w IIS .Cache-Control: no-cache
było za mało.źródło
Sugeruję obejście problemu, aby zmodyfikować sygnaturę funkcji tak, aby wyglądała mniej więcej tak:
getNewRecordID (intRecordType, strTimestamp), a następnie zawsze przekazuje również parametr TimeStamp i po prostu odrzuca tę wartość po stronie serwera. Działa to wokół problemu.
źródło