XMLHttpRequest: Difference between revisions

Content deleted Content added
"The XMLHttpRequest Standard defines an API". It never once refers to XHR as a class, because strictly it isn't one.
m Reverted edits by 94.24.100.90 (talk) to last version by 2601:642:4600:D3B0:4046:B02D:7EB0:D6AC
 
(39 intermediate revisions by 5 users not shown)
Line 18:
| page = 92
| isbn = 978-0-596-10180-0
}}</ref> The ''XMLHttpRequest'' class is a component of [[Ajax (programming)|Ajax programming]]. Prior to Ajax, an[[hyperlink]]s and [[HTML form|form]] neededsubmissions towere bethe completelyprimary sentmechanisms tofor interacting with the server, followedoften byreplacing athe complete browsercurrent page refreshwith another one.<ref name="adp-92"/>
 
==History==
The concept behind the ''XMLHttpRequest'' class was conceived in 2000 by the developers of [[Microsoft Outlook]] – available on the [[Windows 2000]] operating system.<ref name="ALEXHOPMANN_quote1">{{cite web
|url=http://www.alexhopmann.com/xmlhttp.htm
|title=Article on the history of XMLHTTP by an original developer
Line 28:
|archive-url=https://web.archive.org/web/20090130092236/http://www.alexhopmann.com/xmlhttp.htm
|archive-date=2009-01-30|access-date=2009-07-14
|quote=The reality is that the client architecture of GMail appears to follow the rough design of the Exchange 2000 implementation of Outlook Web Access for IE5 and later which shipped way back in 2000.}}</ref> The concept was then implemented within the [[Internet Explorer 5]] (2001) browser's [[Interpreter (computing2001)|interpreter]].{{efn|Modern browsers execute JavaScript using a [[Just-in-time compilation|just-in-time compiler]] called a [[JavaScript engine]].}} However, the original [[Syntax (programming languages)|syntax]] did not use the <code>XMLHttpRequest</code> [[Identifier (computer languages)|identifier]]. Instead, the developers used the identifiers <code>ActiveXObject("Msxml2.XMLHTTP")</code> and <code>ActiveXObject("Microsoft.XMLHTTP")</code>.<ref name="adp-93">{{cite book
| last = Mahemoff
| first = Michael
Line 38:
}}</ref> As of [[Internet Explorer 7]] (2006), all browsers support the <code>XMLHttpRequest</code> identifier.<ref name="adp-93"/>
 
The <code>XMLHttpRequest</code> identifier is now the [[de facto standard|''de facto'' standard]] in all the major browsers, including [[Mozilla|Mozilla's]] [[Gecko (layout engine)|Gecko layout engine]] (2002), [[Konqueror]] (2002), [[Safari (web browser)|Safari]] 1.2 (2004),<ref>{{cite web
|url=http://weblogs.mozillazine.org/hyatt/archives/2004_02.html
|title=Archived news from Mozillazine stating the release date of Safari 1.2
|publisher=Weblogs.mozillazine.org
|access-date=2009-07-14 |archive-date=2009-06-02
|archive-url=https://web.archive.org/web/20090602041255/http://weblogs.mozillazine.org/hyatt/archives/2004_02.html |url-status=dead }}</ref> [[Safari (web browser)|Safari]] 1.2 (2004) and [[Opera (web browser)|Opera]] 8.0 (2005),.<ref>{{cite web
|url=http://www.opera.com/press/releases/2005/06/16/
|title=Press release stating the release date of Opera 8.0 from the Opera website
|publisher=Opera.com
|date=2005-04-19
|access-date=2009-07-14}}</ref>, and [[iCab]] (2005).<ref>{{cite web
|author=Soft-Info.org
|url=http://www.soft-info.org/browsers/icab-10109.html
|title=Detailed browser information stating the release date of iCab 3.0b352
|publisher=Soft-Info.com
|access-date=2009-07-14}}</ref>
 
With the advent of cross-browser JavaScript libraries such as [[jQuery]], developers can invoke XMLHttpRequest functionality indirectly.
 
==Standards==
Line 61 ⟶ 54:
|url=http://www.w3.org/TR/2006/WD-XMLHttpRequest-20060405/
|title=Specification of the XMLHttpRequest object from the Level 1 W3C Working Draft released on April 5th, 2006
|publisher=W3.org |access-date=2009-07-14}}</ref> {{efn|The standard was [[copy editing|edited]] by [[Anne van Kesteren]] of [[Opera Software]] and Dean Jackson of W3C.}} On February 25, 2008, the W3C published the ''Working Draft Level 2'' specification.<ref name="xhr2">{{cite web
|url=http://www.w3.org/TR/2008/WD-XMLHttpRequest2-20080225/
|title=Specification of the XMLHttpRequest object from the Level 2 W3C Working Draft released on February 25th, 2008
Line 70 ⟶ 63:
|publisher=w3.org |access-date=5 December 2011}}</ref>
 
At the end of 2012, the [[WHATWG]] took over development and maintains a [[living document]] using [[Web IDL]].<ref name="xhr-standard">{{cite webreport|last=van Kesteren|first=Anne|title=XMLHttpRequest Living Standard|date=February 19, 2024|url=https://xhr.spec.whatwg.org/commit-snapshots/fdd619d0a13fe4d8af1c9ffdb6de24cb88c53cc0/|access-date=2024-04-09}}</ref>
|url=https://xhr.spec.whatwg.org/#specification-history
|title=XMLHttpRequest Standard/#specification-history}}</ref>
 
==XMLHttpRequest usage==
 
===Constructor===
Generating an asynchronous request to the [[web server]] requires first to [[Instance (computer science)|instantiate]] ([[Object_lifetime#Object_creation|allocate the memory of]]) the ''XMLHttpRequest'' object. The allocated memory is assigned to a [[Variable (computer science)|variable]]. The programming [[statement (computer science)|statement]] in JavaScript to instantiate a new object is '''<code>[[new and delete (C++)|new]]</code>'''.<ref name="jdg-82">{{cite book
| last = Flanagan
| first = David
| title = JavaScript, The Definitive Guide
| publisher = O'Reilly and Associates
| year = 1998
| page = 82
| isbn = 1-56592-392-8}}</ref> The '''<code>new</code>''' statement is followed by the [[Constructor (object-oriented programming)|constructor function]] of the object. The custom for [[object-oriented programming|object-oriented]] language developers is to invoke the constructor function using same name as the [[Class (computer programming)|class name]].<ref name="pmwd-162">{{cite book
| last1 = Welling
| first1 = Luke
| last2 = Thomson
| first2 = Laura
| title = PHP and MySQL Web Development
| publisher = Sams Publishing
| year = 2005
| page = 162
| isbn = 0-672-32672-8
}}</ref> In this case, the class name is ''XMLHttpRequest''. To instantiate a new ''XMLHttpRequest'' and assign it to the variable named <code>request</code>:
 
<code>var request = new XMLHttpRequest();</code><ref name="xhr_constructor">{{cite web
| title=XMLHttpRequest Standard; The constructor
| url=https://xhr.spec.whatwg.org/#constructors
| access-date=2023-04-10
}}</ref>
 
===The ''open'' method===
The ''open'' method prepares the ''XMLHttpRequest''.<ref name="adp-100">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 100
| isbn = 978-0-596-10180-0
}}</ref> It can accept up to five [[Parameter (computer science)|parameter]]s, but requires only the first two.
 
<code>var request = new XMLHttpRequest();</code>
 
<code>request.open( RequestMethod, SubmitURL, AsynchronousBoolean, UserName, Password );</code>
 
* '''RequestMethod''': The [[Hypertext Transfer Protocol#Request methods|HTTP request method]] may be <code>GET</code> for typical quantities of data. Among the other request methods available, <code>[[POST (HTTP)|POST]]</code> will handle substantial quantities of data.<ref name="adp-96">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 96
| isbn = 978-0-596-10180-0
}}</ref> After the return string is received, then send the <code>DELETE</code> request method to <code>.open()</code> to free the ''XMLHttpRequest'' memory.<ref name="rfc_9110-method_overview">{{cite web
| title=HTTP Documentation
| date=June 2022
| url=https://httpwg.org/specs/rfc9110.html#method.overview
| access-date=2023-04-12
}}</ref> If <code>DELETE</code> is sent, then the SubmitURL parameter may be <code>null</code>.
: * <code>request.open( "DELETE", null );</code>
* '''SubmitURL''': The ''SubmitURL'' is a [[URL]] containing the [[Execution (computing)|execution]] [[filename]] and any [[Parameter (computer programming)|parameters]] that get submitted to the web server. If the URL contains the [[Host (network)|host]] name, it must be the web server that sent the HTML document. Ajax supports the [[same-origin policy]].<ref name="adp-98">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 98
| isbn = 978-0-596-10180-0
}}</ref>
* '''AsynchronousBoolean''': If supplied, it should be set to true. If set to false, then the browser will wait until the return string is received. Programmers are discouraged to set AsynchronousBoolean to false, and browsers may experience an exception error.<ref name="xhr_open_method">{{cite web
| title=XMLHttpRequest Standard; The open method
| url=https://xhr.spec.whatwg.org/#the-open()-method
| access-date=2023-04-12
}}</ref>
* '''UserName''': If supplied, it will help authenticate the user.
* '''Password''': If supplied, it will help authenticate the user.
 
===The ''setRequestHeader'' method===
If the request method of <code>[[POST (HTTP)|POST]]</code> is invoked, then the additional step of sending the [[media type]] of <code>Content-Type: application/x-www-form-urlencoded</code> is required.<ref name="adp-97">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 97
| isbn = 978-0-596-10180-0
}}</ref> The <code>setRequestHeader</code> method allows the program to send this or other [[List of HTTP headers|HTTP header]]s to the web server. Its usage is <code>setRequestHeader( HeaderField, HeaderValue )</code>.<ref name="adp-100"/> To enable the <code>POST</code> request method:
: * <code>request.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );</code>
 
===The ''send'' method===
If the request method of <code>[[POST (HTTP)|POST]]</code> is invoked, then the web server expects the [[HTML form|form data]] to be read from the standard input stream.<ref name="jdg-511">{{cite book
| last = Flanagan
| first = David
| title = JavaScript, The Definitive Guide
| publisher = O'Reilly and Associates
| year = 1998
| page = 511
| isbn = 1-56592-392-8}}</ref> To send the form data to the web server, execute <code>request.send( FormData )</code>, where FormData is a text string. If the request method of <code>GET</code> is invoked, then the web server expects only the default headers.<ref name="adp-26">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 26
| isbn = 978-0-596-10180-0
}}</ref> To send the default headers, execute <code>request.send( null )</code>.{{efn|The <code>null</code> placeholder is currently in retirement but recommended.}}
 
===The ''onreadystatechange'' event listener===
<code>onreadystatechange</code> is a [[Callback (computer programming)|callback method]] that is periodically executed throughout the Ajax lifecycle.<ref name="adp-25">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 25
| isbn = 978-0-596-10180-0
}}</ref> To set a callback method named <code>ReadyStateMethod()</code>, the [[Syntax (programming languages)|syntax]] is <code>request.onreadystatechange = ReadyStateMethod</code>.{{efn|For safety, this assignment should follow the execution of <code>request.open()</code>.}} For convenience, the syntax allows for an [[Anonymous function|anonymous method]] to be defined.<ref name="adp-25"/> To define an anonymous callback method:
<syntaxhighlight lang="javascript">
var request = new XMLHttpRequest();
 
request.onreadystatechange = function()
{
// code omitted
}
</syntaxhighlight>
 
The ''XMLHttpRequest'' lifecycle progresses through several stages – from 0 to 4. Stage 0 is before the <code>open()</code> method is invoked, and stage 4 is when the text string has arrived.<ref name="adp-26">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 26
| isbn = 978-0-596-10180-0
}}</ref> To monitor the lifecycle, ''XMLHttpRequest'' has available the <code>readyState</code> [[Attribute (computing)|attribute]]. Stages 1-3 are ambiguous and interpretations vary across browsers.<ref name="adp-100"/> Nonetheless, one interpretation is:<ref name="adp-100"/>
* Stage 0: Uninitialized
* Stage 1: Loading
* Stage 2: Loaded
* Stage 3: Interactive
* Stage 4: Completed
 
When <code>readyState</code> reaches 4, then the text string has arrived and is set in the <code>responseText</code> attribute.
 
<syntaxhighlight lang="javascript">
var request = new XMLHttpRequest();
 
request.onreadystatechange = function()
{
if ( request.readyState == 4 )
{
// request.responseText is set
}
}
</syntaxhighlight>
 
==Linux examples==
Upon request, the browser will execute a JavaScript function to transmit a request for the [[web server]] to execute a [[computer program]]. The computer program may be the [[PHP]] [[Interpreter (computing)|interpreter]], another interpreter, or a [[compiler|compiled]] [[executable]]. In any case, the JavaScript function expects a [[String (computer science)|text string]] to be transmitted back and stored in the <code>responseText</code> [[Attribute (computing)|attribute]].<ref name="adp-26">{{cite book
| last = Mahemoff
| first = Michael
| title = Ajax Design Patterns
| publisher = O'Reilly
| year = 2006
| page = 26
| isbn = 978-0-596-10180-0
}}</ref>
 
To create an example JavaScript function:
 
* <code>cd /var/www/html</code>
* Edit a file named <code>ajax_submit.js</code>:
 
<syntaxhighlight lang="javascript">
function ajax_submit( element_id, submit_url )
{
var request = new XMLHttpRequest();
var completed_state = 4;
 
request.onreadystatechange = function()
{
if ( request.readyState == completed_state )
{
document.
getElementById( element_id ).
innerHTML =
request.responseText;
request.open( "DELETE", null );
}
}
 
request.open( "GET", submit_url );
request.send( null );
}
</syntaxhighlight>
 
===PHP example===
[[PHP]] is a [[scripting language]] designed specifically to [[Interface (computing)|interface]] with [[HTML]].<ref name="pmwd-2_quote">{{cite book
| last1 = Welling
| first1 = Luke
| last2 = Thomson
| first2 = Laura
| title = PHP and MySQL Web Development
| publisher = Sams Publishing
| year = 2005
| page = 2
| isbn = 0-672-32672-8
| quote = PHP is a server-side scripting language designed specifically for the Web.
}}</ref> Because the PHP engine is an [[Interpreter (computing)|interpreter]] – interpreting program [[statement (computer science)|statements]] as they are read – there are programming limitations{{efn|Whereas PHP is a rich language and interfaces well with certain [[databases]], it supports only a subset of [[Container (abstract data type)|container types]] and lacks [[declarative language]] constructs.}} and performance costs.{{efn|An interpreter executes each programming statement; however, a compiled program has each [[machine instruction]] ready for the [[CPU]].}} Nonetheless, its simplicity may place the ''XMLHttpRequest'' set of files in the same working directory – probably <code>/var/www/html</code>.
 
====PHP server component====
The ''server component'' of a PHP ''XMLHttpRequest'' is a file located on the server that does not get transmitted to the browser. Instead, the PHP interpreter will open this file and read in its PHP instructions. The ''XMLHttpRequest'' protocol requires it to output a text string.
 
* <code>cd /var/www/html</code>
* Edit a file named <code>ajax.phtml</code>:
<syntaxhighlight lang="PHP">
<?php
echo '<h1>Hello World!</h1>';
?>
</syntaxhighlight>
 
====PHP browser component====
The ''browser component'' of a PHP ''XMLHttpRequest'' is a file located on the server that gets transmitted to the browser. The browser will open this file and read in its HTML instructions.
 
* <code> cd /var/www/html</code>
* Edit a file named <code>ajax.html</code>:
<syntaxhighlight lang="html">
<html>
<head>
<title>Hello World</title>
<script type=text/javascript src=ajax_submit.js></script>
</head>
<body>
<div id=ajax_title></div>
<button onclick="ajax_submit( 'ajax_title', 'ajax.phtml' )">
Submit
</button>
</body>
</syntaxhighlight>
 
* Point your browser to <code>http://localhost/ajax.html</code>
* Press <code>Submit</code>
 
===CGI example===
The [[Common Gateway Interface]] (CGI) process allows browsers to request the [[web server]] to execute [[compiler|compiled]] [[computer program]]s.{{efn|The web server may be configured to execute interpreted programs, also.<ref name="apache_howto_cgi">{{cite web
| title=Apache Tutorial
| url=https://httpd.apache.org/docs/2.4/howto/cgi.html
| access-date=2023-04-10
}}</ref>}}
 
====CGI server component====
The ''server component'' of a CGI ''XMLHttpRequest'' is an [[executable]] file located on the server. The [[operating system]] will open this file and read in its [[machine instructions]]. The ''XMLHttpRequest'' protocol requires the executable to output a text string.
 
Compiled programs have two files: the [[source code]] and a corresponding executable.
 
* <code>cd /usr/lib/cgi-bin</code>
* Edit a file named <code>ajax.c</code>:
<syntaxhighlight lang="c">
#include <stdio.h>
 
==Usage==
void main( void )
Generally, sending a request with XMLHttpRequest has several programming steps.<ref name="holdener">{{cite book|last=Holdener|first=Anthony T. III|title=Ajax: The Definitive Guide|year=2008|pages=70–71, 76}}</ref>
{
/* CGI requires the first line to output: */
printf( "Content-type: text/html\n" );
 
# Create an XMLHttpRequest object by calling a [[Constructor (object-oriented programming)|constructor]]: <syntaxhighlight lang="javascript">var request = new XMLHttpRequest();</syntaxhighlight>
/* CGI requires the second line to output: */
# Call the "open" method to specify the request type, identify the relevant resource, and select synchronous or asynchronous operation: <syntaxhighlight lang="javascript">request.open('GET', '/api/message', true /* asynchronous */);</syntaxhighlight>
printf( "\n" );
# Set an event listener that will be notified when the request's state changes: <syntaxhighlight lang="javascript">request.onreadystatechange = listener;</syntaxhighlight>
# Initiate the request by calling the "send" method: <syntaxhighlight lang="javascript">request.send();</syntaxhighlight>
# Respond to state changes in the event listener. If the server sends response data, by default it is captured in the "responseText" property. When the object stops processing the response, it changes to state 4, the "done" state. <syntaxhighlight lang="javascript">function listener() {
// Check whether the request is done and successful.
if (request.readyState == 4 && request.status == 200)
console.log(request.responseText); // Display the text.
}</syntaxhighlight>
 
Aside from these general steps, XMLHttpRequest has many options to control how the request is sent and how the response is processed. Custom [[HTTP header|header fields]] can be added to the request to indicate how the server should fulfill it,{{sfn|van Kesteren|loc=3.5.2}} and data can be uploaded to the server by providing it in the "send" call.{{sfn|van Kesteren|loc=3.5.6}} The response can be parsed from the [[JSON]] format into a readily usable JavaScript object, or processed gradually as it arrives rather than waiting for the entire text.{{sfn|van Kesteren|loc=3.6.9}} The request can be aborted prematurely{{sfn|van Kesteren|loc=3.5.7}} or set to fail if not completed in a specified amount of time.{{sfn|van Kesteren|loc=3.5.3}}
printf( "<h1>Hello World!</h1>\n" );
}
</syntaxhighlight>
 
==Cross-domain requests==
* Compile the source code to create the executable:
{{main|Cross-origin resource sharing}}
<code>cc ajax.c -o ajax</code>
In the early development of the [[World Wide Web]], it was found possible to breach users' security by the use of JavaScript to exchange information from one web site with that from another less reputable one. All modern browsers therefore implement a [[same origin policy]] that prevents many such attacks, such as [[cross-site scripting]]. XMLHttpRequest data is subject to this security policy, but sometimes web developers want to intentionally circumvent its restrictions. This is sometimes due to the legitimate use of subdomains as, for example, making an XMLHttpRequest from a page created by <code>foo.example.com</code> for information from <code>bar.example.com</code> will normally fail.
 
Various alternatives exist to circumvent this security feature, including using [[JSONP]], [[Cross-Origin Resource Sharing]] (CORS) or alternatives with plugins such as [[Adobe Flash|Flash]] or [[Microsoft Silverlight|Silverlight]] (both now deprecated). Cross-origin XMLHttpRequest is specified in W3C's XMLHttpRequest Level 2 specification.<ref>{{cite web|url=http://www.w3.org/TR/XMLHttpRequest2/ |title=XMLHttpRequest Level 2 |access-date=2013-11-14}}</ref> Internet Explorer did not implement CORS until version 10. The two previous versions (8 and 9) offered similar functionality through the XDomainRequest (XDR) API. CORS is now supported by all modern browsers (desktop and mobile).<ref>{{cite web|url=http://caniuse.com/cors |title=Can I use Cross-Origin Resource Sharing? |access-date=2013-11-14}}</ref>
or
 
The CORS protocol has several restrictions, with two models of support. The ''simple'' model does not allow setting custom request headers and omits [[HTTP Cookie|cookies]]. Further, only the HEAD, GET and POST [[Hypertext Transfer Protocol#Request methods|request methods]] are supported, and POST only allows the following [[MIME]] types: "text/plain", "application/x-www-urlencoded" and "[[MIME#form-data|multipart/form-data]]". Only "text/plain" was initially supported.<ref>{{cite web|url=http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx |title=XDomainRequest - Restrictions, Limitations and Workarounds |access-date=2013-11-14}}</ref> The other model detects when one of the ''non-simple'' features are requested and sends a ''pre-flight request''<ref>{{cite web|url=http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0 |title=7.1.5 Cross-Origin Request with Preflight |access-date=2014-04-25}}</ref> to the server to negotiate the feature.
<code>sudo cc ajax.c -o ajax</code>
 
==Fetch alternative==
====CGI browser component====
Program flow using asynchronous XHR callbacks can present difficulty with readability and maintenance. [[ECMAScript]] 2015 (ES6) added the [[Futures and promises|promise]] construct to simplify asynchronous logic. Browsers have since implemented the alternative <code>fetch()</code> interface to achieve the same functionality as XHR using [[Promise (computing)|promises]] instead of callbacks.
The CGI browser component is the same as the PHP browser component, except for a slight change in the <code>submit_url</code>. The [[Syntax (programming languages)|syntax]] to tell the web server to execute an executable is <code>/cgi-bin/</code> followed by the filename. For security, the executable must reside in a [[chroot|chroot jail]]. In this case, the jail is the directory <code>/usr/lib/cgi-bin/</code>.{{efn|The web server may be configured to add other executable directories.<ref name="apache_howto_cgi"/>}}
 
Fetch is also standardized by WHATWG.<ref>{{cite web |url=https://fetch.spec.whatwg.org/ |title = Fetch Standard}}</ref>
* <code> cd /var/www/html</code>
* Edit a file named <code>ajax.html</code>:
<syntaxhighlight lang="html">
<html>
<head>
<title>Hello World</title>
<script type=text/javascript src=ajax_submit.js></script>
</head>
<body>
<div id=ajax_title></div>
<button onclick="ajax_submit( 'ajax_title', '/cgi-bin/ajax' )">
Submit
</button>
</body>
</syntaxhighlight>
 
===Example===
* Point your browser to <code>http://localhost/ajax.html</code>
<syntaxhighlight lang="JavaScript">
* Press <code>Submit</code>
fetch('/api/message')
.then(response => {
if (response.status != 200) throw new Error('Request failed');
return response.text();
})
.then(text => {
console.log(text);
});</syntaxhighlight>
 
==See also==