XMLHttpRequest

XMLHttpRequest ( XHR ) är ett API i form av ett objekt vars metoder överför data mellan en webbläsare och en webbserver . Objektet tillhandahålls av webbläsarens JavaScript- miljö. I synnerhet är hämtning av data från XHR i syfte att kontinuerligt modifiera en laddad webbsida det underliggande konceptet för Ajax -design. Trots namnet kan XHR användas med andra protokoll än HTTP och data kan vara i form av inte bara XML , utan även JSON , HTML eller vanlig text .

WHATWG upprätthåller en XHR-standard som ett levande dokument . Pågående arbete på W3C för att skapa en stabil specifikation är baserat på ögonblicksbilder av WHATWG-standarden.

Historia

Konceptet bakom XMLHttpRequest -objektet skapades ursprungligen av utvecklarna av Outlook Web Access (av Microsoft) för Microsoft Exchange Server 2000 . Ett gränssnitt kallat IXMLHTTPrequest utvecklades och implementerades i den andra versionen av MSXML -biblioteket med detta koncept. Den andra versionen av MSXML-biblioteket levererades med Internet Explorer 5.0 i mars 1999, vilket ger tillgång, via ActiveX , till gränssnittet IXMLHTTPRequest med hjälp av XMLHTTP - omslaget i MSXML-biblioteket.

Internet Explorer version 5 och 6 definierade inte XMLHttpRequest-objektidentifieraren i sina skriptspråk eftersom själva XMLHttpRequest-identifieraren inte var standard vid tidpunkten för deras utgivning. Bakåtkompatibilitet kan uppnås genom objektdetektering om XMLHttpRequest-identifieraren inte finns. Microsoft lade till XMLHttpRequest- objektidentifieraren till sina skriptspråk i Internet Explorer 7.0 som släpptes i oktober 2006.

Mozilla - projektet utvecklade och implementerade ett gränssnitt som heter nsIXMLHttpRequest i Gecko- layoutmotorn. Detta gränssnitt utformades för att fungera så nära Microsofts IXMLHTTPRequest -gränssnitt som möjligt. Mozilla skapade en wrapper för att använda detta gränssnitt genom ett JavaScript-objekt som de kallade XMLHttpRequest . XMLHttpRequest , men det var inte helt funktionellt förrän så sent som version 1.0 av Gecko släpptes den 5 juni 2002. XMLHttpRequest-objektet blev en de facto standard i andra större webbklienter, implementerade i Safari 1.2 släpptes i februari 2004, Konqueror , Opera 8.0 släpptes i april 2005 och iCab 3.0b352 släpptes i september 2005.

Med tillkomsten av JavaScript-bibliotek över webbläsare som jQuery , kan utvecklare anropa XMLHttpRequest-funktionalitet indirekt.

Standarder

World Wide Web Consortium publicerade en Working Draft- specifikation för XMLHttpRequest -objektet den 5 april 2006, redigerad av Anne van Kesteren från Opera Software och Dean Jackson från W3C. Dess mål är "att dokumentera en minsta uppsättning interoperabla funktioner baserat på befintliga implementeringar, vilket gör det möjligt för webbutvecklare att använda dessa funktioner utan plattformsspecifik kod."

W3C publicerade också en annan Working Draft- specifikation för XMLHttpRequest -objektet, "XMLHttpRequest Level 2", den 25 februari 2008. Nivå 2 består av utökad funktionalitet till XMLHttpRequest -objektet, inklusive, men inte begränsat till, framstegshändelser, stöd för kors- platsförfrågningar och hantering av byteströmmar. I slutet av 2011 övergavs nivå 2-specifikationen och absorberades i den ursprungliga specifikationen.

I slutet av 2012 tog WHATWG över utvecklingen och upprätthåller en levnadsstandard med hjälp av Web IDL . W3C:s nuvarande utkast är baserade på ögonblicksbilder av WHATWG -standarden.

HTTP-förfrågan

Följande avsnitt visar hur en begäran som använder XMLHttpRequest-objektet fungerar i en överensstämmande användaragent baserat på W3C Working Draft. Eftersom W3C-standarden för XMLHttpRequest-objektet fortfarande är ett utkast, kanske användaragenter inte följer alla funktioner i W3C-definitionen och något av följande kan komma att ändras. Extrem försiktighet bör tas i beaktande när du skriptar med XMLHttpRequest-objektet över flera användaragenter. Den här artikeln kommer att försöka lista inkonsekvenserna mellan de stora användaragenterna.

Den öppna metoden

HTTP- och HTTPS - förfrågningarna för XMLHttpRequest-objektet måste initieras med den öppna metoden . Den här metoden måste anropas innan den faktiska sändningen av en begäran för att validera och lösa den begärandemetod, URL och URI -användarinformation som ska användas för begäran. Den här metoden garanterar inte att webbadressen finns eller att användarinformationen är korrekt. Denna metod kan acceptera upp till fem parametrar , men kräver bara två, för att initiera en begäran.

öppen (Metod, URL, Asynkron, Användarnamn, Lösenord)

Metodens första parameter är en textsträng som anger vilken HTTP-förfrågningsmetod som ska användas. De begäransmetoder som måste stödjas av en överensstämmande användaragent , definierad av W3C -utkastet för XMLHttpRequest-objektet, listas för närvarande som följande.

Begäransmetoderna är dock inte begränsade till de som anges ovan. W3C-utkastet säger att en webbläsare kan stödja ytterligare begärandemetoder efter eget gottfinnande.

Metodens andra parameter är en annan textsträng , den här anger URL :en för HTTP-förfrågan. W3C rekommenderar att webbläsare ska visa ett fel och inte tillåta begäran om en URL med antingen en annan port eller ihost URI -komponent från det aktuella dokumentet.

Den tredje parametern, ett booleskt värde som indikerar om begäran kommer att vara asynkron eller inte, är inte en parameter som krävs enligt W3C-utkastet. Standardvärdet för denna parameter bör antas vara sant av en W3C-konform användaragent om den inte tillhandahålls. En asynkron begäran ("true") kommer inte att vänta på ett serversvar innan den fortsätter med exekveringen av det aktuella skriptet. Den kommer istället att anropa onreadystatechange- händelselyssnaren för XMLHttpRequest-objektet under de olika stegen av begäran. En synkron begäran ("false") kommer dock att blockera exekvering av det aktuella skriptet tills begäran har slutförts, vilket inte anropar onreadystatechange- händelselyssnaren . Observera att från och med Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), Blink 39.0 (Chrome) och Edge 13, har synkrona förfrågningar på huvudtråden fasats ut på grund av deras negativa inverkan på användarupplevelsen eftersom de kommer att orsaka frysning i användargränssnittet medan tråden utför begäran.

De fjärde och femte parametrarna är användarnamnet respektive lösenordet . Dessa parametrar, eller bara användarnamnet, kan tillhandahållas för autentisering och auktorisering om det krävs av servern för denna begäran.

 

  
       
      
    
 var  xmlhttp  ;  if  (  fönster  .  XMLHttpRequest  )  {  xmlhttp  =  new  XMLHttpRequest  ();  xmlhttp  .  open  (  "GET"  ,  filsökväg  ,  false  );  xmlhttp  .  skicka  (  noll  );  } 

Metoden setRequestHeader _

Efter framgångsrik initiering av en begäran kan setRequestHeader- metoden för XMLHttpRequest-objektet anropas för att skicka HTTP-huvuden med begäran.

setRequestHeader( Namn, Värde)

Den första parametern i denna metod är rubrikens textsträngsnamn. Den andra parametern är textsträngens värde. Denna metod måste anropas för varje rubrik som måste skickas med begäran. Alla rubriker som bifogas här kommer att tas bort nästa gång den öppna metoden anropas i en W3C-anpassad användaragent.

Sändningsmetoden _ _

För att skicka en HTTP-förfrågan måste sändningsmetoden för XMLHttpRequest anropas. Denna metod accepterar en enda parameter som innehåller innehållet som ska skickas med begäran.

skicka data )

Denna parameter kan utelämnas om inget innehåll behöver skickas. W3C-utkastet anger att denna parameter kan vara vilken typ som helst som är tillgänglig för skriptspråket så länge den kan omvandlas till en textsträng, med undantag för DOM- dokumentobjektet . Om en användaragent inte kan serialisera parametern, bör parametern ignoreras. Firefox 3.0.x och tidigare versioner ger dock ett undantag om send anropas utan ett argument.

Om parametern är ett DOM- dokumentobjekt , bör en användaragent säkerställa att dokumentet omvandlas till välformaterad XML med hjälp av kodningen som anges av egenskapen inputEncoding för dokumentobjektet . Om Content-Type- förfrågningshuvudet inte har lagts till via setRequestHeader ännu, bör det automatiskt läggas till av en överensstämmande användaragent som "application/xml;charset= charset ," där charset är den kodning som används för att koda dokumentet.

Om användaragenten är konfigurerad att använda en proxyserver kommer XMLHttpRequest-objektet att modifiera begäran på lämpligt sätt för att ansluta till proxyn istället för ursprungsservern, och skicka proxy-auktoriseringshuvuden som konfigurerats.

Onreadystatechange - händelselyssnaren

Om den öppna metoden för XMLHttpRequest-objektet anropades med den tredje parametern inställd på true för en asynkron begäran, kommer onreadystatechange- händelseavlyssnaren att anropas automatiskt för var och en av följande åtgärder som ändrar egenskapen readyState för XMLHttpRequest-objektet.

Statsförändringar fungerar så här:

  • Tillstånd Beskrivning
 0 Begäran initieras inte. 1 Begäran har ställts in.  2 Begäran har skickats.  3 Begäran är under behandling.  4 Begäran är klar.  
  • Efter att den öppna metoden har anropats framgångsrikt, ska egenskapen readyState för objektet XMLHttpRequest tilldelas värdet 1 (OPENED).
  • Efter att sändmetoden har anropats och HTTP-svarshuvudena har tagits emot, ska egenskapen readyState för objektet XMLHttpRequest tilldelas värdet 2 (HEADERS_RECEIVED).
  • När HTTP-svarsinnehållet börjar laddas, ska egenskapen readyState för objektet XMLHttpRequest tilldelas värdet 3 (LOADING).
  • När HTTP-svarsinnehållet har laddats klart ska egenskapen readyState för XMLHttpRequest-objektet tilldelas värdet 4 (DONE).

Lyssnaren kommer endast att svara på tillståndsändringar som inträffar efter att lyssnaren har definierats. För att detektera tillstånd 1 och 2 måste lyssnaren definieras innan den öppna metoden anropas. Den öppna metoden måste anropas innan sändningsmetoden anropas.

    
    
         
       
        
    

  
   
                                                                 
   var  request  =  new  XMLHttpRequest  ();  begäran  .  onreadystatechange  =  function  ()  {  var  DONE  =  detta  .  KLAR  ||  4  ;  if  (  this  .  readyState  ===  DONE  ){  alert  (  this  .  readyState  );  }  };  begäran  .  open  (  'GET'  ,  'somepage.xml'  ,  true  );  begäran  .  setRequestHeader  (  'X-Requested-With'  ,  'XMLHttpRequest'  );  // Berättar för servern att detta anrop görs för ajax-ändamål.  // De flesta bibliotek som jQuery/Prototype/Dojo gör denna  begäran  .  skicka  (  noll  );  // Inga data behöver skickas tillsammans med begäran. 

HTTP-svaret

Efter ett framgångsrikt och avslutat anrop till sändningsmetoden för XMLHttpRequest, om serversvaret var välformaterad XML och Content-Type- huvudet som skickats av servern förstås av användaragenten som en Internet-medietyp för XML, egenskapen responseXML av XMLHttpRequest-objektet kommer att innehålla ett DOM-dokumentobjekt. En annan egenskap, responseText , kommer att innehålla serverns svar i klartext av en överensstämmande användaragent, oavsett om det uppfattades som XML eller inte.

Förfrågningar över flera domäner

I den tidiga utvecklingen av World Wide Web visade sig det vara möjligt att bryta användarnas säkerhet genom att använda JavaScript för att utbyta information från en webbplats med den från en annan mindre ansedd. Alla moderna webbläsare implementerar därför samma ursprungspolicy som förhindrar många sådana attacker, såsom cross-site scripting . XMLHttpRequest-data är föremål för denna säkerhetspolicy, men ibland vill webbutvecklare avsiktligt kringgå dess begränsningar. Detta beror ibland på legitim användning av underdomäner, eftersom till exempel att göra en XMLHttpRequest från en sida skapad av foo.example.com för information från bar.example.com normalt kommer att misslyckas.

Det finns olika alternativ för att kringgå denna säkerhetsfunktion, inklusive att använda JSONP , Cross-Origin Resource Sharing (CORS) eller alternativ med plugins som Flash eller Silverlight (båda nu föråldrade). Cross-origin XMLHttpRequest specificeras i W3C:s XMLHttpRequest Level 2-specifikation. Internet Explorer implementerade inte CORS förrän version 10. De två tidigare versionerna (8 och 9) erbjöd liknande funktionalitet genom XDomainRequest (XDR) API. CORS stöds nu av alla moderna webbläsare (dator och mobil).

CORS-protokollet har flera begränsningar, med två stödmodeller. Den enkla modellen tillåter inte att anpassa rubriker för begäranden och utelämnar cookies . Vidare stöds endast HEAD-, GET- och POST- begäransmetoderna , och POST tillåter endast följande MIME- typer: "text/plain", "application/x-www-urlencoded" och " multipart/form-data ". Endast "text/plain" stöddes initialt. Den andra modellen upptäcker när en av de icke-enkla funktionerna efterfrågas och skickar en förfrågan före flygning till servern för att förhandla om funktionen.

Hämta alternativ

Programflöde som använder asynkrona XHR-återuppringningar kan ge svårigheter med läsbarhet och underhåll. ECMAScript 2015 (ES6) lade till löfteskonstruktionen för att förenkla asynkron logik. Webbläsare har sedan dess implementerat det alternativa fetch() -gränssnittet för att uppnå samma funktionalitet som XHR genom att använda löften istället för callbacks.

Fetch är också standardiserat av WHATWG.

Exempel

 
     
     
          
                                           
    
  
        
        
    
 fetch  (  "somepage.xml"  ,  {  method  :  "GET"  ,  headers  :  {  "X-Requested-With"  :  "XMLHttpRequest"  // Berättar för servern att detta anrop är gjort för AJAX-ändamål.  // De flesta bibliotek som jQuery/ Prototyp/Dojo gör detta  }  }).  then  ((  svar  )  =>  {  if  (  svar  .  status  ==  200  )  {  alert  (  svar  .  status  );  }  }); 

Se även

externa länkar