Z bardzo prostą semantyką buforowania: jeśli parametry są takie same (a adres URL jest taki sam), to jest to strzał w dziesiątkę. Czy to jest możliwe? Zalecana?
źródło
Z bardzo prostą semantyką buforowania: jeśli parametry są takie same (a adres URL jest taki sam), to jest to strzał w dziesiątkę. Czy to jest możliwe? Zalecana?
Odpowiedni dokument RFC 2616 w sekcji 9.5 (POST) pozwala na buforowanie odpowiedzi na wiadomość POST, jeśli używasz odpowiednich nagłówków.
Odpowiedzi na tę metodę nie podlegają buforowaniu, chyba że odpowiedź zawiera odpowiednie pola nagłówka Cache-Control lub Expires. Jednak odpowiedź 303 (Zobacz inne) może służyć do skierowania agenta użytkownika do pobrania zasobu buforowanego.
Należy pamiętać, że sama RFC stwierdza wyraźnie w punkcie 13 (buforowanie w HTTP), że cache musi unieważnić odpowiednią jednostkę po POST żądanie .
Niektóre metody HTTP MUSZĄ powodować, że pamięć podręczna unieważnia jednostkę. Jest to jednostka, do której odwołuje się identyfikator URI żądania albo nagłówki Location lub Content-Location (jeśli są obecne). Te metody to:
- PUT - DELETE - POST
Nie jest dla mnie jasne, w jaki sposób te specyfikacje mogą pozwolić na znaczące buforowanie.
Zostało to również odzwierciedlone i dokładniej wyjaśnione w RFC 7231 (sekcja 4.3.3.), Który zastępuje RFC 2616.
Odpowiedzi na żądania POST można
zapisywać w pamięci podręcznej tylko wtedy, gdy zawierają wyraźne informacje o aktualności (patrz sekcja 4.2.1 w [RFC7234]).
Jednak buforowanie POST nie jest powszechnie stosowane. W przypadkach, gdy serwer pochodzenia życzy sobie, aby klient mógł buforować wynik POST w sposób, który może być ponownie wykorzystany przez późniejszy GET, serwer pochodzenia MOŻE wysłać odpowiedź 200 (OK) zawierającą wynik i lokalizację zawartości pole nagłówka, które ma taką samą wartość jak efektywny identyfikator URI żądania POST (sekcja 3.1.4.2).
Zgodnie z tym, wynik buforowanego testu POST (jeśli serwer wskaże taką możliwość) może być następnie wykorzystany jako wynik żądania GET dla tego samego URI.
Zgodnie z RFC 2616 sekcja 9.5:
Więc TAK, możesz buforować odpowiedź na żądanie POST, ale tylko wtedy, gdy nadejdzie z odpowiednimi nagłówkami. W większości przypadków nie chcesz buforować odpowiedzi. Ale w niektórych przypadkach - na przykład jeśli nie zapisujesz żadnych danych na serwerze - jest to całkowicie właściwe.
Należy jednak pamiętać, że wiele przeglądarek, w tym aktualna Firefox 3.0.10, nie buforuje odpowiedzi POST niezależnie od nagłówków. IE zachowuje się pod tym względem inteligentniej.
Teraz chcę wyjaśnić tutaj pewne zamieszanie dotyczące RFC 2616 S. 13.10. Metoda POST na URI nie „unieważnia zasobu do buforowania”, jak niektórzy tutaj stwierdzili. Powoduje, że poprzednio zbuforowana wersja tego identyfikatora URI jest przestarzała, nawet jeśli jej nagłówki kontroli pamięci podręcznej wskazywały na świeżość i dłuższy czas trwania.
źródło
GET
iPOST
. Jeśli jesteś pamięcią podręczną znajdującą się między klientem a serwerem, widziszGET /foo
i buforujesz odpowiedź. Następny widziszPOST /foo
to jesteś zobowiązany do unieważnienia pamięci podręcznej odpowiedź odGET /foo
nawet jeżeliPOST
odpowiedź nie zawiera żadnych nagłówków kontroli cache ponieważ są one takie same URI , więc następnyGET /foo
będzie musiał revalidate nawet jeśli oryginalne nagłówki wskazane cache będzie nadal na żywo (jeśli nie widziałeśPOST /foo
prośby)But in some cases - such as if you are not saving any data on the server - it's entirely appropriate.
. Jaki jest zatem sens takiego API POST w pierwszej kolejności?Ogólny:
Zasadniczo POST nie jest idempotentną operacją . Nie możesz więc używać go do buforowania. GET powinna być operacją idempotentną, więc jest powszechnie używana do buforowania.
Zobacz sekcję 9.1 protokołu HTTP 1.1 RFC 2616 S. 9.1 .
Poza semantyką metody GET:
Sama metoda POST jest semantycznie przeznaczona do wysyłania czegoś do zasobu. POST nie może być buforowany, ponieważ jeśli zrobisz coś raz, dwa razy vs trzy razy, za każdym razem zmieniasz zasoby serwera. Każde żądanie ma znaczenie i powinno zostać dostarczone na serwer.
Sama metoda PUT jest semantycznie przeznaczona do umieszczania lub tworzenia zasobu. Jest to operacja idempotentna, ale nie będzie używana do buforowania, ponieważ w międzyczasie mogło nastąpić DELETE.
Sama metoda DELETE jest semantycznie przeznaczona do usuwania zasobu. Jest to operacja idempotentna, ale nie będzie używana do buforowania, ponieważ w międzyczasie mogło dojść do PUT.
Odnośnie buforowania po stronie klienta:
Przeglądarka internetowa zawsze przekaże Twoje żądanie, nawet jeśli otrzyma odpowiedź z poprzedniej operacji POST. Na przykład możesz wysyłać e-maile za pomocą Gmaila w odstępie kilku dni. Mogą mieć ten sam temat i treść, ale należy wysłać oba e-maile.
Odnośnie buforowania proxy:
Serwer proxy HTTP, który przekazuje Twoją wiadomość do serwera, nigdy nie buforowałby niczego poza żądaniem GET lub HEAD.
Odnośnie buforowania serwera:
Serwer domyślnie nie obsługiwałby automatycznie żądania POST poprzez sprawdzanie swojej pamięci podręcznej. Ale oczywiście żądanie POST może zostać wysłane do twojej aplikacji lub dodatku i możesz mieć własną pamięć podręczną, z której odczytujesz, gdy parametry są takie same.
Unieważnienie zasobu:
Sprawdzenie protokołu HTTP 1.1 RFC 2616 S. 13.10 pokazuje, że metoda POST powinna unieważnić zasób do buforowania.
źródło
Jeśli buforujesz odpowiedź POST, musi ona być skierowana do aplikacji internetowej. To właśnie oznacza „Odpowiedzi na tę metodę nie mogą być buforowane, chyba że odpowiedź zawiera odpowiednie pola nagłówka Cache-Control lub Expires”.
Można spokojnie założyć, że aplikacja, która wie, czy wyniki testu POST są idempotentne, decyduje o dołączeniu niezbędnych i odpowiednich nagłówków kontroli pamięci podręcznej. Jeśli nagłówki sugerujące, że buforowanie jest dozwolone, są obecne, aplikacja informuje cię, że POST jest w rzeczywistości super-GET; że użycie POST było wymagane tylko ze względu na ilość niepotrzebnych i nieistotnych (ze względu na użycie URI jako klucza pamięci podręcznej) danych niezbędnych do wykonania idempotentnej operacji.
Przy tym założeniu następujące GET-y mogą być obsługiwane z pamięci podręcznej.
Aplikacja, której nie udało się dołączyć niezbędnych i poprawnych nagłówków w celu rozróżnienia między buforowanymi i niepodlegającymi buforowaniu odpowiedziami POST, jest winna wszelkich nieprawidłowych wyników buforowania.
To powiedziawszy, każdy POST, który trafia do pamięci podręcznej, wymaga weryfikacji przy użyciu warunkowych nagłówków. Jest to wymagane, aby odświeżyć zawartość pamięci podręcznej, aby wyniki testu POST nie były odzwierciedlane w odpowiedziach na żądania do czasu wygaśnięcia okresu istnienia obiektu.
źródło
Mark Nottingham przeanalizował, kiedy można buforować odpowiedź testu POST. Zauważ, że kolejne żądania, które chcą skorzystać z buforowania, muszą być żądaniami GET lub HEAD. Zobacz także semantykę http
https://www.mnot.net/blog/2012/09/24/caching_POST .
źródło
Jeśli zastanawiasz się, czy możesz zapisać w pamięci podręcznej żądanie posta i spróbować znaleźć odpowiedź na to pytanie, prawdopodobnie nie odniesiesz sukcesu. Podczas wyszukiwania „żądania publikacji w pamięci podręcznej” pierwszym wynikiem jest pytanie StackOverflow.
Odpowiedzi są zagmatwaną mieszanką tego, jak powinno działać buforowanie, jak działa buforowanie zgodnie z RFC, jak buforowanie powinno działać zgodnie z RFC i jak działa buforowanie w praktyce. Zacznijmy od RFC, zobaczmy, jak faktycznie działa przeglądarka, a następnie porozmawiajmy o sieciach CDN, GraphQL i innych problematycznych obszarach.
RFC 2616
Zgodnie z RFC, żądania POST muszą unieważniać pamięć podręczną:
Ten język sugeruje, że żądania POST nie mogą być buforowane, ale to nieprawda (w tym przypadku). Pamięć podręczna jest unieważniana tylko dla wcześniej zapisanych danych. Dokument RFC (wydaje się) wyraźnie wyjaśnia, że tak,
POST
żądania można buforować :Pomimo tego języka ustawienie
Cache-Control
nie może buforować kolejnychPOST
żądań do tego samego zasobu.POST
żądania należy wysyłać do serwera:W jaki sposób to ma sens? Cóż, nie buforujesz
POST
żądania, buforujesz zasób.Treść odpowiedzi POST może być buforowana tylko dla kolejnych żądań GET do tego samego zasobu. Ustaw nagłówek
Location
lubContent-Location
w odpowiedzi POST, aby poinformować, który zasób reprezentuje treść. Zatem jedynym technicznie poprawnym sposobem buforowania żądania POST jest wykonanie kolejnych GET w tym samym zasobie.Prawidłowa odpowiedź to:
Chociaż RFC zezwala na buforowanie żądań do tego samego zasobu, w praktyce przeglądarki i sieci CDN nie implementują tego zachowania i nie pozwalają na buforowanie żądań POST.
Źródła:
Demonstracja zachowania przeglądarki
Biorąc pod uwagę następującą przykładową aplikację JavaScript (index.js):
Biorąc pod uwagę następującą przykładową stronę internetową (index.html):
Zainstaluj NodeJS, Express i uruchom aplikację JavaScript. Otwórz stronę internetową w przeglądarce. Wypróbuj kilka różnych scenariuszy, aby przetestować zachowanie przeglądarki:
Pokazuje to, że nawet jeśli można ustawić nagłówki
Cache-Control
iContent-Location
odpowiedzi, nie ma sposobu, aby pamięć podręczna przeglądarki była żądaniem HTTP POST.Czy muszę przestrzegać RFC?
Zachowania przeglądarki nie można konfigurować, ale jeśli nie jesteś przeglądarką, niekoniecznie obowiązują Cię zasady RFC.
Jeśli piszesz kod aplikacji, nic nie stoi na przeszkodzie, aby jawnie buforować żądania POST (pseudokod):
Sieci CDN, serwery proxy i bramy również nie muszą być zgodne ze specyfikacją RFC. Na przykład, jeśli używasz Fastly jako swojej sieci CDN, Fastly umożliwia pisanie niestandardowej logiki VCL w celu buforowania żądań POST .
Czy powinienem buforować żądania POST?
To, czy żądanie POST powinno być buforowane, czy nie, zależy od kontekstu.
Na przykład możesz wysyłać zapytania do Elasticsearch lub GraphQL za pomocą POST, gdy Twoje zapytanie bazowe jest idempotentne. W takich przypadkach buforowanie odpowiedzi w pamięci podręcznej może mieć sens lub nie, w zależności od przypadku użycia.
W RESTful API żądania POST zwykle tworzą zasób i nie powinny być buforowane. Jest to również rozumienie przez RFC POST, że nie jest to operacja idempotentna.
GraphQL
Jeśli używasz GraphQL i potrzebujesz buforowania HTTP w sieciach CDN i przeglądarkach, zastanów się, czy wysyłanie zapytań za pomocą metody GET spełnia Twoje wymagania zamiast POST . Uwaga: różne przeglądarki i sieci CDN mogą mieć różne limity długości URI, ale lista bezpiecznych operacji (biała lista zapytań), jako najlepsza praktyka dla zewnętrznych aplikacji GraphQL, może skrócić identyfikatory URI.
źródło
Jeśli jest to coś, co w rzeczywistości nie zmienia danych w Twojej witrynie, powinno to być żądanie GET. Nawet jeśli jest to formularz, nadal możesz ustawić go jako żądanie pobierania. Chociaż, jak wskazują inni, można buforować wyniki testu POST, nie miałoby to sensu semantycznego, ponieważ z definicji POST zmienia dane.
źródło
W przypadku przeglądarki Firefox 27.0 i httpfox 19 maja 2014 r. Zobaczyłem jedną linię: 00: 03: 58.777 0,488 657 (393) POST (Cache) text / html https://users.jackiszhp.info/S4UP
Oczywiście odpowiedź metody post jest przechowywana w pamięci podręcznej, a także w https. Nie do wiary!
źródło
POST jest używany w stanowym Ajaxie. Zwracanie buforowanej odpowiedzi na POST niweczy kanał komunikacyjny i skutki uboczne otrzymania wiadomości. To jest bardzo, bardzo złe. To także prawdziwy ból do wytropienia. Gorąco polecam przeciwko.
Trywialnym przykładem może być wiadomość, że efektem ubocznym jest wypłata pensji w wysokości 10 000 USD w bieżącym tygodniu. NIE chcesz, aby komunikat „OK, przeszedł!” strona wstecz, która została zapisana w pamięci podręcznej w zeszłym tygodniu. Inne, bardziej złożone przypadki w świecie rzeczywistym skutkują podobną wesołością.
źródło