Żądanie XMLHttp — XMLHttpRequest

XMLHttpRequest ( XHR ) to API w postaci obiektu, którego metody przenoszą dane między przeglądarką internetową a serwerem WWW . Obiekt jest dostarczany przez środowisko JavaScript przeglądarki . W szczególności pobieranie danych z XHR w celu ciągłej modyfikacji załadowanej strony internetowej jest podstawową koncepcją projektowania Ajax . Wbrew nazwie, XHR może być używany z protokołami innymi niż HTTP, a dane mogą mieć postać nie tylko XML , ale także JSON , HTML czy zwykłego tekstu .

WHATWG utrzymuje standard XHR jako żywy dokument . Trwające prace w W3C nad stworzeniem stabilnej specyfikacji opierają się na migawkach standardu WHATWG.

Historia

Koncepcja obiektu XMLHttpRequest została pierwotnie stworzona przez twórców programu Outlook Web Access (firmy Microsoft) dla Microsoft Exchange Server 2000 . Interfejs o nazwie IXMLHTTPRequest został opracowany i wdrożony w drugiej wersji MSXML biblioteki przy użyciu tego pojęcia. Druga wersja biblioteki MSXML została dostarczona z Internet Explorerem 5.0 w marcu 1999 roku, umożliwiając dostęp poprzez ActiveX do interfejsu IXMLHTTPRequest przy użyciu wrappera XMLHTTP biblioteki MSXML.

Internet Explorer w wersjach 5 i 6 nie zdefiniował identyfikatora obiektu XMLHttpRequest w swoich językach skryptowych, ponieważ sam identyfikator XMLHttpRequest nie był standardem w momencie ich wydania. Kompatybilność wsteczną można osiągnąć poprzez wykrywanie obiektów, jeśli identyfikator XMLHttpRequest nie istnieje. Firma Microsoft dodała identyfikator obiektu XMLHttpRequest do swoich języków skryptowych w programie Internet Explorer 7.0 wydanym w październiku 2006 roku.

Projekt Mozilla opracował i zaimplementował interfejs o nazwie nsIXMLHttpRequest w silniku układu Gecko . Ten interfejs został zaprojektowany tak, aby działał jak najbliżej interfejsu IXMLHTTPRequest firmy Microsoft . Mozilla stworzyła wrapper do używania tego interfejsu przez obiekt JavaScript, który nazwali XMLHttpRequest . Obiekt XMLHttpRequest był dostępny już w wersji Gecko 0.6 wydanej 6 grudnia 2000 roku, ale nie był w pełni funkcjonalny dopiero w wersji 1.0 Gecko wydanej 5 czerwca 2002 roku. Obiekt XMLHttpRequest stał się de facto standardem w innych głównych klienty internetowe, zaimplementowane w Safari 1.2 wydanej w lutym 2004, Konqueror , Opera 8.0 wydanej w kwietniu 2005 oraz iCab 3.0b352 wydanej we wrześniu 2005.

Wraz z pojawieniem się bibliotek JavaScript obsługujących wiele przeglądarek, takich jak jQuery , programiści mogą pośrednio wywoływać funkcjonalność XMLHttpRequest.

Normy

World Wide Web Consortium opublikowało projekt pracy specyfikację dla XMLHttpRequest obiektu w dniu 5 kwietnia 2006 roku, stworzony przez Anne van Kesteren z Opera Software i Dean Jackson z W3C. Jego celem jest „udokumentowanie minimalnego zestawu interoperacyjnych funkcji w oparciu o istniejące implementacje, umożliwiając programistom internetowym korzystanie z tych funkcji bez kodu specyficznego dla platformy”.

W3C opublikowało również inną specyfikację Working Draft dla obiektu XMLHttpRequest , "XMLHttpRequest Level 2", 25 lutego 2008. Poziom 2 obejmuje rozszerzoną funkcjonalność obiektu XMLHttpRequest , w tym między innymi zdarzenia postępu, obsługę żądania witryn i obsługa strumieni bajtów. Pod koniec 2011 roku specyfikacja poziomu 2 została porzucona i wchłonięta do oryginalnej specyfikacji.

Pod koniec 2012 roku WHATWG przejęło rozwój i utrzymuje standard życia przy użyciu Web IDL . Aktualne wersje robocze W3C są oparte na migawkach standardu WHATWG .

żądanie HTTP

Poniższe sekcje pokazują, w jaki sposób żądanie używające obiektu XMLHttpRequest działa w zgodnym programie użytkownika opartym na roboczej wersji roboczej W3C. Ponieważ standard W3C dla obiektu XMLHttpRequest jest wciąż wersją roboczą, programy użytkownika mogą nie przestrzegać wszystkich funkcji definicji W3C i każdy z poniższych może ulec zmianie. Należy zachować szczególną ostrożność podczas pisania skryptów z obiektem XMLHttpRequest w wielu programach użytkownika. W tym artykule postaram się wymienić niespójności między głównymi programami użytkownika.

Otwarta metoda

W HTTP i HTTPS żądania obiektu XMLHttpRequest muszą być inicjowane przez otwartej metody . Ta metoda musi zostać wywołana przed faktycznym wysłaniem żądania, aby zweryfikować i rozwiązać metodę żądania, adres URL i informacje o użytkowniku URI, które mają być używane w żądaniu. Ta metoda nie gwarantuje, że adres URL istnieje ani że informacje o użytkowniku są poprawne. Ta metoda może zaakceptować do pięciu parametrów , ale wymaga tylko dwóch, aby zainicjować żądanie.

open( Method, URL, Asynchronous, UserName, Password )

Pierwszym parametrem metody jest ciąg tekstowy wskazujący metodę żądania HTTP do użycia. Metody żądania, które muszą być obsługiwane przez zgodnego agenta użytkownika , zdefiniowane w wersji roboczej W3C dla obiektu XMLHttpRequest, są obecnie wymienione w następujący sposób.

  • GET (obsługiwane przez Internet Explorer 7+, Mozilla 1+ )
  • POST (obsługiwany przez IE7 +, Mozilla 1+)
  • HEAD (obsługiwane przez IE7+)
  • POŁOŻYĆ
  • KASOWAĆ
  • OPCJE (obsługiwane przez IE7+)

Jednak metody żądania nie ograniczają się do tych wymienionych powyżej. Wersja robocza W3C stwierdza, że ​​przeglądarka może obsługiwać dodatkowe metody żądań według własnego uznania.

Drugim parametrem metody jest inny ciąg tekstowy , ten wskazujący adres URL żądania HTTP. W3C zaleca, aby przeglądarki zgłaszały błąd i nie zezwalały na żądanie adresu URL z innym portem lub komponentem URI ihost niż bieżący dokument.

Trzeci parametr, wartość logiczna wskazująca, czy żądanie będzie asynchroniczne, nie jest wymaganym parametrem w wersji roboczej W3C. Domyślna wartość tego parametru powinna zostać uznana za true przez agenta użytkownika zgodnego z W3C, jeśli nie jest podana. Żądanie asynchroniczne („prawda”) nie będzie czekać na odpowiedź serwera przed kontynuowaniem wykonywania bieżącego skryptu. Będzie zamiast Invoke w onreadystatechange detektora zdarzeń z obiektu XMLHttpRequest na różnych etapach wniosku. Żądanie synchroniczne ("false") zablokuje jednak wykonanie bieżącego skryptu do czasu zakończenia żądania, a tym samym nie wywoła detektora zdarzeń onreadystatechange . Zwróć uwagę, że począwszy od Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), Blink 39.0 (Chrome) i Edge 13, żądania synchroniczne w głównym wątku zostały wycofane ze względu na ich negatywny wpływ na wrażenia użytkownika, ponieważ będą powodować zawieszanie się interfejsu użytkownika, gdy wątek wykonuje żądanie.

Czwarty i piąty parametr to odpowiednio nazwa użytkownika i hasło . Te parametry, lub tylko nazwa użytkownika, mogą być dostarczone do uwierzytelniania i autoryzacji, jeśli jest to wymagane przez serwer dla tego żądania.

var xmlhttp;

if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", filepath, false);
    xmlhttp.send(null);
}

SetRequestHeader Sposób

Po pomyślnej inicjalizacji żądania można wywołać metodę setRequestHeader obiektu XMLHttpRequest w celu wysłania nagłówków HTTP z żądaniem.

setRequestHeader( Name, Value )

Pierwszym parametrem tej metody jest nazwa ciągu tekstowego nagłówka. Drugi parametr to wartość ciągu tekstowego. Ta metoda musi być wywoływana dla każdego nagłówka, który ma zostać wysłany z żądaniem. Wszelkie dołączone tutaj nagłówki zostaną usunięte przy następnym wywołaniu metody open w agencie użytkownika zgodnym z W3C.

Wyślij metoda

Aby wysłać żądanie HTTP, należy wywołać metodę send XMLHttpRequest. Ta metoda akceptuje pojedynczy parametr zawierający treść do wysłania wraz z żądaniem.

send( Data )

Ten parametr można pominąć, jeśli nie trzeba wysyłać treści. Wersja robocza W3C stwierdza, że ​​ten parametr może być dowolnym typem dostępnym dla języka skryptowego, o ile można go przekształcić w ciąg tekstowy, z wyjątkiem obiektu dokumentu DOM . Jeśli klient użytkownika nie może serializować parametru, należy go zignorować. Firefox 3.0.xi wcześniejsze wersje zgłoszą jednak wyjątek, jeśli sendzostanie wywołany bez argumentu.

Jeśli parametr jest obiektem dokumentu DOM , agent użytkownika powinien upewnić się, że dokument został przekształcony w poprawnie sformułowany XML przy użyciu kodowania wskazanego przez właściwość inputEncoding obiektu dokumentu . Jeśli nagłówek żądania Content-Type nie został jeszcze dodany przez setRequestHeader , powinien zostać automatycznie dodany przez zgodnego klienta użytkownika jako „application/xml;charset= charset ”, gdzie charset jest kodowaniem używanym do kodowania dokumentu.

Jeśli agent użytkownika jest skonfigurowany do korzystania z serwera proxy , obiekt XMLHttpRequest odpowiednio zmodyfikuje żądanie, aby połączyć się z serwerem proxy zamiast z serwerem pochodzenia i wysłać Proxy-Authorizationnagłówki zgodnie z konfiguracją.

Onreadystatechange detektor zdarzeń

Jeśli metoda otwarta obiektu XMLHttpRequest została wywołana z trzecim parametrem ustawionym na wartość true dla żądania asynchronicznego, detektor zdarzeń onreadystatechange będzie automatycznie wywoływany dla każdej z następujących akcji zmieniających właściwość readyState obiektu XMLHttpRequest.

Zmiany stanu działają w następujący sposób:

  • Opis stanu
   0		The request is not initialized.
   1		The request has been set up.
   2		The request has been sent.
   3		The request is in process.
   4		The request is completed.
  • Po pomyślnym wywołaniu metody open , właściwości readyState obiektu XMLHttpRequest należy przypisać wartość 1 (OPENED).
  • Po wywołaniu metody send i odebraniu nagłówków odpowiedzi HTTP właściwości readyState obiektu XMLHttpRequest należy przypisać wartość 2 (HEADERS_RECEIVED).
  • Po rozpoczęciu ładowania treści odpowiedzi HTTP do właściwości readyState obiektu XMLHttpRequest należy przypisać wartość 3 (LOADING).
  • Po zakończeniu ładowania treści odpowiedzi HTTP do właściwości readyState obiektu XMLHttpRequest należy przypisać wartość 4 (DONE).

Odbiornik będzie reagował tylko na zmiany stanu, które nastąpią po zdefiniowaniu słuchacza. Aby wykryć stany 1 i 2, detektor musi zostać zdefiniowany przed wywołaniem metody open. Metoda open musi zostać wywołana przed wywołaniem metody send.

var request = new XMLHttpRequest();
request.onreadystatechange = function () {
    var DONE = this.DONE || 4;
    if (this.readyState === DONE){
        alert(this.readyState);
    }
};
request.open('GET', 'somepage.xml', true);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');  // Tells server that this call is made for ajax purposes.
                                                                 // Most libraries like jQuery/Prototype/Dojo do this
request.send(null);  // No data needs to be sent along with the request.

Odpowiedź HTTP

Po udanym i zakończonym wywołaniu metody send XMLHttpRequest, jeśli odpowiedź serwera była poprawnie sformułowanym XML, a nagłówek Content-Type wysłany przez serwer jest rozumiany przez agenta użytkownika jako internetowy typ mediów dla XML, właściwość responseXML obiektu XMLHttpRequest będzie zawierać obiekt dokumentu DOM. Inna właściwość, responseText, będzie zawierać odpowiedź serwera w postaci zwykłego tekstu przez zgodnego klienta użytkownika, niezależnie od tego, czy została zrozumiana jako XML, czy nie.

Żądania między domenami

We wczesnym rozwoju sieci WWW okazało się możliwe naruszenie bezpieczeństwa użytkowników poprzez użycie JavaScript do wymiany informacji z jednej strony internetowej z tą z innej, mniej renomowanej. Wszystkie nowoczesne przeglądarki implementują zatem zasady tego samego pochodzenia, które zapobiegają wielu takim atakom, takim jak cross-site scripting . Dane XMLHttpRequest podlegają tej polityce bezpieczeństwa, ale czasami twórcy stron internetowych chcą celowo obejść jej ograniczenia. Czasami jest to spowodowane legalnym używaniem subdomen, ponieważ na przykład wykonanie XMLHttpRequest ze strony utworzonej przez w foo.example.comcelu uzyskania informacji z bar.example.comzwykle kończy się niepowodzeniem.

Istnieją różne alternatywy umożliwiające obejście tej funkcji zabezpieczeń, w tym używanie JSONP , Udostępnianie zasobów między źródłami (CORS) lub alternatywy z wtyczkami, takimi jak Flash lub Silverlight (oba są teraz przestarzałe). XMLHttpRequest cross-origin jest określony w specyfikacji XMLHttpRequest Level 2 W3C. Internet Explorer nie implementował mechanizmu CORS do wersji 10. Dwie poprzednie wersje (8 i 9) oferowały podobną funkcjonalność za pośrednictwem interfejsu API XDomainRequest (XDR). CORS jest teraz obsługiwany przez wszystkie nowoczesne przeglądarki (komputerowe i mobilne).

Protokół CORS ma kilka ograniczeń, z dwoma modelami wsparcia. Model prosty nie pozwala na ustawianie niestandardowych nagłówków żądań i pomija pliki cookie . Ponadto obsługiwane są tylko metody żądania HEAD, GET i POST , a POST dopuszcza tylko następujące typy MIME : "text/plain", "application/x-www-urlencoded" i " multipart/form-data ". Początkowo obsługiwana była tylko opcja „tekst/zwykły”. Drugi model wykrywa, kiedy żądana jest jedna z nieprostych funkcji i wysyła żądanie przed lotem do serwera w celu wynegocjowania funkcji.

Pobierz alternatywę

Przepływ programu przy użyciu asynchronicznych wywołań zwrotnych XHR może powodować trudności z czytelnością i konserwacją. W ECMAScript 2015 (ES6) dodano konstrukcję obietnicy, aby uprościć logikę asynchroniczną. Od tego czasu przeglądarki wdrożyły alternatywny fetch()interfejs, aby osiągnąć taką samą funkcjonalność jak XHR, używając obietnic zamiast wywołań zwrotnych.

Pobieranie jest również standaryzowane przez WHATWG.

Zobacz też

Bibliografia

Zewnętrzne linki