Przejdź do treści

Jak usunąć zapytanie HTTP OPTIONS?

Ahoy! Od jakiegoś czasu artykuły pojawiają się rzadziej. Znalazłem tego przyczynę!

Pisząc artykuł zawsze staram się opisać wszystko co wiem na dany temat. Tym samym czas jaki muszę wygospodarować na taki artykuł wykracza poza moje możliwości. Szkoda.

Rozwiązanie jest proste. Będę publikował częściej, ale kosztem długości artykułu. Po prostu wpisy będą krótkie.

Jestem ciekaw, czy ta forma przypadnie Wam do gustu.

Baner promujący artykuł

Problem

Piszę aplikację, która będzie hostowana na adresie foo.com. Aplikacja komunikuje się z backend-em, który jest dostępny pod adresem bar.com.

Kto nie wie, co to jest CORS, to zapraszam tutaj.

Podczas komunikacji z backend-em za pomocą zapytania HTTP typu GET albo POST, przed faktycznym zapytaniem, wysyłany jest automatycznie (inicjowany przez przeglądarkę) request typu OPTIONS.

Chciałbym go wyeliminować, aby w DevTools → Network nie widzieć zdublowanych rekordów.

Jak to osiągnąć?

Rozwiązanie

Jeśli w zapytaniu znajdują się nagłówki, które przeglądarka nie rozumie (np. są to customowe nagłówki, które rozumie tylko serwer bar.com), to takie zapytanie zostaje uznane za zapytanie z efektami ubocznymi i musi zostać SPRAWDZONE czy serwer poradzi sobie z jego obsługą.

Zapytanie HTTP OPTIONS jest po to, aby przeglądarka zweryfikowała serwer.

Aby wyeliminować zapytanie HTTP OPTIONS należy spełnić następujące warunki:

  • Używać metody GET, HEAD albo POST
  • Nie używać customowych nagłówków, np. X-USERNAME: root, ani nagłówka Authorization
  • Ustawić nagłówek Content-Type na jeden z następujących:
    • multipart/form-data
    • application/x-www-form-urlencoded
    • text/plain

W moim przypadku pomogło ustawienie Content-Type: text/plain.

Biblioteka, której używałem do zapytań, domyślnie ustawiała nagłówek Content-Type: application/json.

Uwaga

Wysyłanie JSON-a z nagłówkiem text/plain to obejście, a nie rozwiązanie. Serwer musi parsować treść wbrew nagłówkowi, a zapytanie z text/plain może zostać wysłane z dowolnej strony bez sprawdzania przez przeglądarkę, co osłabia ochronę przed atakami CSRF. Lepiej:

  • pozwolić przeglądarce zapamiętać wynik sprawdzenia nagłówkiem Access-Control-Max-Age (wtedy OPTIONS idzie raz na jakiś czas),
  • albo serwować API z tej samej domeny co aplikację (np. przez reverse proxy), bo wtedy CORS w ogóle nie dotyczy zapytań.

Więcej informacji na MDN.

Cya! 👋