Jak wysłać zapytanie POST między domenami za pomocą JavaScript?
Notatki - nie powinno odświeżać strony, a następnie muszę pobrać i przeanalizować odpowiedź.
javascript
ajax
cross-domain
Ido Schacham
źródło
źródło
Odpowiedzi:
Aktualizacja: przed kontynuowaniem każdy powinien przeczytać i zrozumieć samouczek html5rocks na temat CORS. Jest łatwy do zrozumienia i bardzo jasny.
Jeśli kontrolujesz testowany serwer POST, po prostu skorzystaj z „Standardu udostępniania zasobów między źródłami”, ustawiając nagłówki odpowiedzi na serwerze. Ta odpowiedź jest omawiana w innych odpowiedziach w tym wątku, ale moim zdaniem niezbyt jasno.
W skrócie tutaj jest, w jaki sposób osiągnąć POST między domenami z from.com/1.html do to.com/postHere.php (używając PHP jako przykładu). Uwaga: musisz ustawić tylko
Access-Control-Allow-Origin
dlaOPTIONS
żądań NON - ten przykład zawsze ustawia wszystkie nagłówki dla mniejszego fragmentu kodu.W konfiguracji postHere.php:
Umożliwia to Twojemu skryptowi wykonywanie testów POST, GET i OPCJI między domenami. Stanie się jasne, gdy będziesz czytać dalej ...
Skonfiguruj POST między domenami z JS (przykład jQuery):
Po wykonaniu testu POST w kroku 2 przeglądarka wyśle do serwera metodę „OPCJE”. Jest to „wąchanie” przez przeglądarkę, aby sprawdzić, czy serwer jest fajny, kiedy go POSTINGujesz. Serwer odpowiada komunikatem „Access-Control-Allow-Origin”, który informuje przeglądarkę, że OK może POST | GET | ORIGIN, jeśli żądanie pochodzi z „ http://from.com ” lub „ https://from.com ”. Ponieważ serwer jest w porządku, przeglądarka prześle drugie żądanie (tym razem POST). Dobrą praktyką jest, aby klient ustawiał typ zawartości, którą wysyła - więc musisz również na to pozwolić.
MDN ma świetny opis dotyczący kontroli dostępu HTTP , który szczegółowo opisuje sposób działania całego przepływu. Według ich dokumentów powinien on „działać w przeglądarkach obsługujących XMLHttpRequest w różnych witrynach”. Jest to jednak trochę mylące, ponieważ MYŚLĘ, że tylko nowoczesne przeglądarki umożliwiają POST między domenami. Sprawdziłem tylko, że działa z Safari, Chrome, FF 3.6.
Jeśli to zrobisz, pamiętaj o następujących kwestiach:
źródło
400 Bad Request
naOPTIONS
życzenie. a wfirefox
drugiej prośbiePOST
nigdy się nie składa. :(Jeśli kontrolujesz serwer zdalny, prawdopodobnie powinieneś użyć CORS, jak opisano w tej odpowiedzi ; jest obsługiwany w IE8 i nowszych wersjach oraz we wszystkich najnowszych wersjach FF, GC i Safari. (Ale w IE8 i 9 CORS nie zezwala na wysyłanie plików cookie w żądaniu.)
Tak więc, jeśli nie kontrolujesz zdalnego serwera lub jeśli potrzebujesz obsługi IE7 lub potrzebujesz plików cookie i musisz obsługiwać IE8 / 9, prawdopodobnie będziesz chciał użyć techniki iframe.
Oto przykładowy kod; Przetestowałem to na IE6, IE7, IE8, IE9, FF4, GC11, S5.
Strzec się! Nie będzie można bezpośrednio odczytać odpowiedzi testu POST, ponieważ element iframe istnieje w osobnej domenie. Ramki nie mogą komunikować się ze sobą z różnych domen; to jest polityka tego samego pochodzenia .
Jeśli kontrolujesz serwer zdalny, ale nie możesz używać CORS (np. Ponieważ korzystasz z IE8 / IE9 i musisz używać plików cookie), istnieją sposoby obejścia zasad tego samego pochodzenia, na przykład za pomocą
window.postMessage
i / lub jedna z wielu bibliotek pozwalająca na wysyłanie wiadomości między ramkami między domenami w starszych przeglądarkach:Jeśli nie kontrolujesz zdalnego serwera, nie możesz odczytać odpowiedzi testu POST, kropka. W przeciwnym razie spowodowałoby to problemy z bezpieczeństwem.
źródło
Pseudo kod
Prawdopodobnie chcesz nadać styl iframe, aby był ukryty i miał absolutną pozycję. Przeglądarka nie zezwala na publikowanie w wielu witrynach, ale jeśli tak, to w jaki sposób to zrobić.
źródło
Nie komplikuj:
POST między domenami:
użyj
crossDomain: true,
nie powinien odświeżać strony:
Nie, nie odświeży strony, ponieważwywołanie zwrotne
success
luberror
asynchroniczne zostanie wywołane, gdy serwer odeśle odpowiedź.Przykładowy skrypt:
źródło
crossDomain: true
dziwnie nie ma absolutnie nic wspólnego z prawdziwymi żądaniami między domenami. Jeśli żądanie dotyczy wielu domen, jquery automatycznie ustawia wartość true.Jeśli masz dostęp do wszystkich zaangażowanych serwerów, umieść w nagłówku odpowiedzi żądanej strony w innej domenie:
PHP:
Na przykład w kodzie xmlrpc.php Drupala zrobiłbyś to:
Prawdopodobnie powoduje to problem z bezpieczeństwem i należy upewnić się, że podjęto odpowiednie środki w celu zweryfikowania żądania.
źródło
Sprawdź
post_method
funkcję w http://taiyolab.com/mbtweet/scripts/twitterapi_call.js - dobry przykład opisanej powyżej metody iframe.źródło
Utwórz dwie ukryte ramki iframe (dodaj „display: none;” do stylu css). Ustaw drugi element iframe na coś we własnej domenie.
Utwórz ukryty formularz, ustaw jego metodę na „wysyłanie” za pomocą target = twoja pierwsza ramka iframe i opcjonalnie ustaw kod na „multipart / form-data” (myślę, że chcesz zrobić POST, ponieważ chcesz wysyłać dane wieloczęściowe, takie jak zdjęcia ?)
Gdy wszystko będzie gotowe, należy wysłać formularz POST ().
Jeśli możesz poprosić drugą domenę o zwrócenie javascript, który wykona komunikację między domenami za pomocą iframe ( http://softwareas.com/cross-domain-communication-with-frrames ), to masz szczęście i możesz uchwycić odpowiedź także.
Oczywiście, jeśli chcesz używać swojego serwera jako serwera proxy, możesz tego wszystkiego uniknąć. Po prostu prześlij formularz na własny serwer, który przekaże żądanie do drugiego serwera (zakładając, że drugi serwer nie jest skonfigurowany do zauważania rozbieżności w adresie IP), uzyskaj odpowiedź i zwróć cokolwiek zechcesz.
źródło
Jeszcze jedna ważna rzecz do zapamiętania !!! W powyższym przykładzie opisano sposób użycia
JQuery 1.6 i niższe ma błąd w XDN między domenami. Według Firebug nie wysłano żadnych próśb oprócz OPCJI. Nie postuj. W ogóle.
Spędziłem 5 godzin na testowaniu / dostrajaniu mojego kodu. Dodanie dużej liczby nagłówków na zdalnym serwerze (skrypcie). Bez żadnego efektu. Ale później zaktualizowałem bibliotekę JQuery do wersji 1.6.4 i wszystko działa jak urok.
źródło
Jeśli chcesz to zrobić w środowisku ASP.net MVC z JQuery AJAX, wykonaj następujące kroki: (jest to podsumowanie rozwiązania oferowanego w tym wątku)
Załóżmy, że „caller.com” (może być dowolną witryną) musi publikować na „server.com” (aplikacja ASP.net MVC)
Na Web.config aplikacji „server.com” dodaj następującą sekcję:
Na „server.com” wykonamy następującą akcję na kontrolerze (zwaną „Home”), na której będziemy publikować:
Następnie z „caller.com” wyślij dane z formularza (z identyfikatorem HTML „formId”) do „server.com” w następujący sposób:
źródło
Jest jeszcze jeden sposób (przy użyciu funkcji HTML5). Możesz użyć iframe proxy hostowanego w tej innej domenie, wysyłasz wiadomość za pomocą postMessage do tego iframe, a następnie iframe może wykonać żądanie POST (w tej samej domenie) i postMessage z powrotem z reposnse do okna nadrzędnego.
rodzic na sender.com
iframe na reciver.com
źródło
Wysoki poziom .... Musisz mieć skonfigurowaną nazwę serwera na swoim serwerze, aby other-serve.your-server.com wskazywał na other-server.com.
Twoja strona dynamicznie tworzy niewidoczny element iframe, który działa jak Twój transport do other-server.com. Następnie musisz komunikować się przez JS ze swojej strony na other-server.com i mieć oddzwonienia, które zwracają dane z powrotem na twoją stronę.
Możliwe, ale wymaga koordynacji ze strony twoj-server.com i other-server.com
źródło
Myślę, że najlepszym sposobem jest użycie XMLHttpRequest (np. $ .Ajax (), $ .post () w jQuery) z jednym z wielu wypełniaczy do udostępniania zasobów między źródłami https://github.com/Modernizr/Modernizr/wiki/HTML5- Cross-Browser-Polyfills # wiki-CORS
źródło
To stare pytanie, ale jakaś nowa technologia może komuś pomóc.
Jeśli masz dostęp administracyjny do drugiego serwera, możesz użyć projektu Forource opensource, aby zrealizować test POST między domenami. Forge zapewnia międzyplatformowe opakowanie JavaScript XmlHttpRequest, które wykorzystuje interfejs API surowego gniazda Flash. POST można nawet wykonać przez TLS.
Powodem, dla którego potrzebujesz dostępu administracyjnego do serwera, na którym publikujesz POST, jest to, że musisz zapewnić zasady między domenami, które zezwalają na dostęp z Twojej domeny.
http://github.com/digitalbazaar/forge
źródło
Wiem, że to stare pytanie, ale chciałem podzielić się moim podejściem. Używam cURL jako proxy, bardzo łatwe i spójne. Utwórz stronę php o nazwie subm.php i dodaj następujący kod:
Następnie w swoim js (tutaj jQuery):
źródło
Powinno to być możliwe dzięki niestandardowej tabeli YQL + JS XHR, spójrz na: http://developer.yahoo.com/yql/guide/index.html
Używam go do skrobania html po stronie klienta (js), działa dobrze (mam pełny odtwarzacz audio, z wyszukiwaniem w internecie / listach odtwarzania / tekstach / informacjach z ostatniego fm, wszystkie klienty js + YQL)
źródło
CORS jest dla Ciebie. CORS to „Udostępnianie zasobów między źródłami”, jest sposobem wysyłania żądania między domenami. Teraz XMLHttpRequest2 i Fetch API obsługują CORS i może wysyłać żądania POST i GET
Ale ma swoje ograniczenia. Serwer musi konkretnie twierdzić, że kontrola dostępu-Allow-Origin nie może być ustawiona na „*”.
A jeśli chcesz, aby jakieś pochodzenie mogło wysłać do Ciebie żądanie, potrzebujesz JSONP (musisz także ustawić Access-Control-Allow-Origin , ale może to być „*”)
W przypadku wielu sposobów żądania, jeśli nie wiesz, jak dokonać wyboru, myślę, że potrzebujesz do tego pełnego funkcjonalnego komponentu. Pozwól, że przedstawię prosty komponent https://github.com/Joker-Jelly/catta
Jeśli korzystasz z nowoczesnej przeglądarki (> IE9, Chrome, FF, Edge itp.), Bardzo polecam użycie prostego, ale pięknego komponentu https://github.com/Joker-Jelly/catta . Nie ma zależności, mniej niż 3 KB i obsługuje Fetch, AJAX i JSONP z tą samą śmiertelną składnią próbki i opcjami.
Obsługuje także importowanie do projektu, takie jak moduł ES6, CommonJS, a nawet
<script>
HTML.źródło
Jeśli masz dostęp do serwera między domenami i nie chcesz dokonywać żadnych zmian kodu po stronie serwera, możesz użyć biblioteki o nazwie - „xdomain”.
Jak to działa:
Krok 1: Serwer 1: dołącz bibliotekę xdomain i skonfiguruj domenę podrzędną jako urządzenie podrzędne:
Krok 2: Na serwerze między domenami utwórz plik proxy.html i dołącz serwer 1 jako wzorzec:
Krok 3:
Teraz możesz wykonać wywołanie AJAX do proxy.html jako punktu końcowego z serwera server1. To pomija żądanie CORS. Biblioteka wewnętrznie korzysta z rozwiązania iframe, które działa z poświadczeniami i wszystkimi możliwymi metodami: GET, POST itp.
Zapytanie kod ajax:
źródło