edytuj 13.09.2018 : dodano pewne szczegóły dotyczące tej prośby przed lotem i sposobu jej uniknięcia na końcu tej odpowiedzi.
OPTIONS
żądania są tym, co nazywamy pre-flight
żądaniami Cross-origin resource sharing (CORS)
.
Są one niezbędne, gdy wysyłasz żądania z różnych źródeł w określonych sytuacjach.
To żądanie przed lotem jest wysyłane przez niektóre przeglądarki jako środek bezpieczeństwa, aby upewnić się, że wykonane żądanie jest zaufane przez serwer. Oznacza to, że serwer rozumie, że metoda, pochodzenie i nagłówki wysyłane na żądanie są bezpieczne.
Twój serwer nie powinien ignorować, ale obsłużyć te żądania za każdym razem, gdy próbujesz wykonać żądania krzyżowego pochodzenia.
Dobry zasób można znaleźć tutaj http://enable-cors.org/
Jednym ze sposobów radzenia sobie z nimi w celu zapewnienia wygody jest upewnienie się, że dla dowolnej ścieżki z OPTIONS
metodą serwer wysyła odpowiedź z tym nagłówkiem
Access-Control-Allow-Origin: *
To powie przeglądarce, że serwer jest gotów odpowiedzieć na żądania z dowolnego źródła.
Aby uzyskać więcej informacji na temat dodawania obsługi CORS na serwerze, zobacz poniższy schemat blokowy
http://www.html5rocks.com/static/images/cors_server_flowchart.png
edycja 2018-09-13
OPTIONS
Żądanie CORS jest uruchamiane tylko w niektórych przypadkach, jak wyjaśniono w dokumentach MDN :
Niektóre żądania nie wyzwalają inspekcji wstępnej CORS. Są to tak zwane „proste żądania” w tym artykule, chociaż specyfikacja Fetch (która definiuje CORS) nie używa tego terminu. Żądanie, które nie uruchamia inspekcji wstępnej CORS - tak zwane „proste żądanie” - to takie, które spełnia wszystkie następujące warunki:
Jedynymi dozwolonymi metodami są:
Oprócz nagłówków ustawianych automatycznie przez agenta użytkownika (na przykład Connection, User-Agent lub dowolny z innych nagłówków o nazwach zdefiniowanych w specyfikacji Fetch jako „zabroniona nazwa nagłówka”), jedynymi nagłówkami, które mogą być ręcznie ustawione są te, które specyfikacja Fetch definiuje jako „nagłówek żądania zabezpieczonego przez CORS”, które są:
- Zaakceptować
- Zaakceptuj język
- Język treści
- Typ zawartości (ale zwróć uwagę na dodatkowe wymagania poniżej)
- DPR
- Łącze w dół
- Zapisz dane
- Szerokość rzutni
- Szerokość
Jedynymi dozwolonymi wartościami nagłówka Content-Type są:
- application / x-www-form-urlencoded
- multipart / form-data
- Zwykły tekst
Żadne detektory zdarzeń nie są zarejestrowane w żadnym obiekcie XMLHttpRequestUpload używanym w żądaniu; są one dostępne za pomocą właściwości XMLHttpRequest.upload.
Żądanie nie zawiera obiektu ReadableStream.
curl
do interfejsu API, to działa, ale gdy uruchamiam z Chrome, pojawia się błąd?Origin
nagłówek do żądania, aby zasymulować, jakby żądanie pochodziło od określonego hosta (np. Twojastrona.com). Możesz także symulować żądania inspekcji wstępnej, ustawiając metodę HTTP żądaniaOPTIONS
iAccess-Control-*
nagłówkówPrzeszedłem przez ten problem, poniżej jest mój wniosek na ten temat i moje rozwiązanie.
Zgodnie ze strategią CORS (zdecydowanie zalecamy przeczytanie o niej) Nie możesz po prostu zmusić przeglądarki do zaprzestania wysyłania żądania OPCJE, jeśli uzna to za konieczne.
Istnieją dwa sposoby obejścia tego:
Access-Control-Max-Age
dla żądania OPCJEProste zapytanie
Proste zapytanie krzyżowe to takie, które spełnia wszystkie następujące warunki:
Jedynymi dozwolonymi metodami są:
Oprócz nagłówków ustawianych automatycznie przez agenta użytkownika (np. Connection, User-Agent itp.), Jedynymi nagłówkami, które można ustawiać ręcznie, są:
Jedynymi dozwolonymi wartościami nagłówka Content-Type są:
Proste zapytanie nie spowoduje zgłoszenia OPCJI przed lotem.
Ustaw pamięć podręczną dla testu OPCJE
Możesz ustawić
Access-Control-Max-Age
żądanie OPCJE, aby nie sprawdzało uprawnienia ponownie, dopóki nie wygaśnie.Notowane ograniczenie
Access-Control-Max-Age
Is600
, która wynosi 10 minut, zgodnie z chromem kodu źródłowegoAccess-Control-Max-Age
działa tylko dla jednego zasobu za każdym razem, na przykładGET
żądania z tą samą ścieżką URL, ale różne zapytania będą traktowane jako różne zasoby. Zatem żądanie do drugiego zasobu nadal wyzwala żądanie inspekcji wstępnej.źródło
Access-Control-Max-Age
. To jest klucz tutaj. Pomaga to uniknąć nadmiernych żądań inspekcji wstępnej.application/json
tylko dlatego, że sprawia, że twoje zapytanie nie jest „proste” (a tym samym uruchamia CORS). Przeglądarka wykonuje swoją pracę. Ustaw serwer tak, aby zwracał coś takiego jak nagłówek,Access-Control-Max-Age: 86400
a przeglądarka nie wyśle ponownie żądania OPCJE przez 24 godziny.Proszę odnieść się do tej odpowiedzi na temat faktycznego zapotrzebowania na OPCJE przed lotem: CORS - Jaka jest motywacja do wprowadzenia wniosków o lot wstępny?
Aby wyłączyć żądanie OPTIONS, należy spełnić poniższe warunki dla żądania ajax:
application/x-www-form-urlencoded
,multipart/form-data
lubtext/plain
Odniesienie: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
źródło
application/xml
lubapplication/json
nie są „niestandardowymi nagłówkami HTTP”. Sam nagłówek byłby,Content-Type
a nazwanie go „niestandardowym” byłoby mylące.Gdy masz otwartą konsolę debugowania i
Disable Cache
włączoną opcję, żądania inspekcji wstępnej będą zawsze wysyłane (tj. Przed każdym żądaniem). jeśli nie wyłączysz pamięci podręcznej, żądanie przed lotem zostanie wysłane tylko raz (na serwer)źródło
Tak, można uniknąć żądania opcji. Żądanie opcji to żądanie wstępnego sprawdzenia, gdy wysyłasz (publikujesz) dowolne dane do innej domeny. Jest to problem bezpieczeństwa przeglądarki. Możemy jednak użyć innej technologii: warstwy transportowej iframe. Zdecydowanie zalecam zapomnienie o jakiejkolwiek konfiguracji CORS i skorzystanie z gotowego rozwiązania, które będzie działać wszędzie.
Spójrz tutaj: https://github.com/jpillora/xdomain
I działający przykład: http://jpillora.com/xdomain/
źródło
Dla programisty, który rozumie powód, dla którego istnieje, ale musi uzyskać dostęp do interfejsu API, który nie obsługuje wywołań OPTIONS bez autoryzacji, potrzebuję tymczasowej odpowiedzi, aby móc rozwijać się lokalnie, dopóki właściciel interfejsu API nie doda odpowiedniej obsługi SPA CORS lub nie otrzymam interfejsu API proxy gotowy do pracy.
Odkryłem, że możesz wyłączyć CORS w Safari i Chrome na komputerze Mac.
Wyłącz zasady tego samego pochodzenia w Chrome
Chrome: Zamknij Chrome, otwórz terminal i wklej to polecenie:
open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Safari: Wyłączanie zasad tego samego pochodzenia w Safari
źródło
Jak już wspomniano w poprzednich postach,
OPTIONS
prośby istnieją z jakiegoś powodu. Jeśli masz problem z długimi czasami reakcji z serwera (np. Połączenie zagraniczne), możesz również poprosić przeglądarkę o buforowanie żądań inspekcji wstępnej.Poproś serwer o odpowiedź z
Access-Control-Max-Age
nagłówkiem, a w przypadku żądań kierowanych do tego samego punktu końcowego żądanie kontroli wstępnej zostanie zapisane w pamięci podręcznej i nie będzie już występować.źródło
OPTIONS
żądania będą buforowane z tym nagłówkiem, jest dość nieprzejrzysty we wszystkich dokumentach CORS, które przeczytałem.Rozwiązałem ten problem jak.
To jest tylko dla rozwoju. Z tym czekam 9ms i 500ms, a nie 8s i 500ms. Mogę to zrobić, ponieważ produkcyjna aplikacja JS będzie na tym samym komputerze co produkcja, więc nie będzie jej,
OPTIONS
ale programowanie jest moje lokalne.źródło
Nie możesz, ale możesz uniknąć CORS za pomocą JSONP.
źródło
Po spędzeniu półtora dnia na próbach rozwiązania podobnego problemu odkryłem, że ma to związek z IIS .
Mój projekt interfejsu API sieci Web został skonfigurowany w następujący sposób:
Nie miałem specyficznych dla CORS opcji konfiguracji w węźle web.config> system.webServer, jak widziałem w tak wielu postach
Brak kodu specyficznego dla CORS w pliku global.asax lub w kontrolerze jako dekorator
Problemem były ustawienia puli aplikacji .
Udało tryb rurociąg został ustawiony na klasyczny ( zmienił go na zintegrowany ) i tożsamość została ustalona do usługi sieciowej ( zmienił go do ApplicationPoolIdentity )
Zmiana tych ustawień (i odświeżenie puli aplikacji) naprawiła to dla mnie.
źródło
Dla mnie działało zaimportowanie „github.com/gorilla/handlers”, a następnie użycie go w następujący sposób:
Gdy tylko wykonam żądanie POST Ajax i dołączę do niego dane JSON, Chrome zawsze doda nagłówek Content-Type, który nie był w mojej poprzedniej konfiguracji Dozwolonych Kierowników.
źródło
Jedno rozwiązanie, z którego korzystałem w przeszłości - załóżmy, że Twoja witryna znajduje się w domenie mydomain.com, i musisz wysłać zapytanie ajax do foreigndomain.com
Skonfiguruj przepisywanie IIS z Twojej domeny na domenę obcą - np
w witrynie mydomain.com - możesz wtedy złożyć to samo żądanie pochodzenia i nie ma potrzeby żądania opcji :)
źródło
Można to rozwiązać w przypadku użycia serwera proxy, który przechwytuje żądanie i zapisuje odpowiednie nagłówki. W szczególnym przypadku Lakieru byłyby to zasady:
}
źródło
Być może istnieje rozwiązanie (ale go nie przetestowałem): możesz użyć CSP (Content Security Policy), aby włączyć domenę zdalną, a przeglądarki mogą pominąć weryfikację żądania CORS OPTIONS.
Jeśli znajdę trochę czasu, przetestuję to i zaktualizuję ten post!
CSP: https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy
Specyfikacja CSP: https://www.w3.org/TR/CSP/
źródło