User Tools

Site Tools


ajax:make_an_ajax_request_using_xmlhttprequest

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
ajax:make_an_ajax_request_using_xmlhttprequest [2016/07/04 11:33] – created peterajax:make_an_ajax_request_using_xmlhttprequest [2020/07/15 09:30] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== AJAX - Make an AJAX request using XMLHttpRequest ====== ====== AJAX - Make an AJAX request using XMLHttpRequest ======
- 
-===== Objective ===== 
  
 To fetch the content of a URI using an **XMLHttpRequest** object in JavaScript. To fetch the content of a URI using an **XMLHttpRequest** object in JavaScript.
Line 94: Line 92:
 Response types allowed by the XMLHttpRequest specification are: Response types allowed by the XMLHttpRequest specification are:
  
-^responseType^ decoded^ parsed^ response^ +^responseType^decoded^parsed^response^ 
-|arraybuffer no| no| ArrayBuffer| +|arraybuffer|no|no|ArrayBuffer| 
-|blob| no| no| Blob| +|blob|no|no|Blob| 
-|document| yes| as HTML or XML Document| +|document|yes|as HTML or XML|Document| 
-|json| yes| as JSON (varies)| +|json|yes|as JSON|(varies)| 
-|text| yes| no| DOMString|+|text|yes|no|DOMString|
  
 The default value (which is the empty string) has similar behaviour to text, but with some additional rules for determining the character set of XML documents. The default value (which is the empty string) has similar behaviour to text, but with some additional rules for determining the character set of XML documents.
Line 108: Line 106:
 Because the HTTP request occurs asynchronously, you will normally want to be notified when it has finished.  The most portable way to do this is by means of the onreadystatechange event handler.  This refers to the readyState attribute of the XMLHttpRequest object, which can take the following values: Because the HTTP request occurs asynchronously, you will normally want to be notified when it has finished.  The most portable way to do this is by means of the onreadystatechange event handler.  This refers to the readyState attribute of the XMLHttpRequest object, which can take the following values:
  
-|0| UNSENT| The object has been constructed.| +|0|UNSENT|The object has been constructed.| 
-|1| OPENED| The open method has been successfully called.| +|1|OPENED|The open method has been successfully called.| 
-|2| HEADERS_RECEIVED| Reception of response headers is complete.| +|2|HEADERS_RECEIVED|Reception of response headers is complete.| 
-|3| LOADING| Reception of response body is in progress.| +|3|LOADING|Reception of response body is in progress.| 
-|4| DONE| Reception of response has either completed or failed.|+|4|DONE|Reception of response has either completed or failed.|
  
 Of these, the state most likely to be of interest is DONE. Since it does not by itself distinguish between success and failure, it is then necessary to check the HTTP status code.  This can be found in the status attribute.  Values in the range 200 to 299 indicate that the request was successful: Of these, the state most likely to be of interest is DONE. Since it does not by itself distinguish between success and failure, it is then necessary to check the HTTP status code.  This can be found in the status attribute.  Values in the range 200 to 299 indicate that the request was successful:
Line 236: Line 234:
   * Use cached credentials (such as cookies, or usernames and passwords for HTTP authentication) for sites that have been accessed using the same web browser.  In this case it is immaterial whether the targetted URL is local or remote with respect to the client.   * Use cached credentials (such as cookies, or usernames and passwords for HTTP authentication) for sites that have been accessed using the same web browser.  In this case it is immaterial whether the targetted URL is local or remote with respect to the client.
  
-To prevent this, browsers check whether the request is directed back to the site from which the web page originated. If so then the request is allowed, on the basis that the website owner has responsibility for ensuring that pages within the website do not invoke scripts which put the website at risk.  The details of this policy are documented in RFC 6454. For URIs which contain a hostname there are three components which must match:+To prevent this, browsers check whether the request is directed back to the site from which the web page originated. If so then the request is allowed, on the basis that the website owner has responsibility for ensuring that pages within the website do not invoke scripts which put the website at risk.  The details of this policy are documented in RFC 6454 [https://www.ietf.org/rfc/rfc6454.txt].  For URIs which contain a hostname there are three components which must match:
  
   * the URI scheme,   * the URI scheme,
Line 242: Line 240:
   * the port number.   * the port number.
  
-Both the URI scheme and hostname are normalised to lower case before comparison.  The appropriate default port is used if none has been specified. For URIs without a hostname there is significant variation between browsers, and you should not assume that any access will be available.+Both the URI scheme and hostname are normalised to lower case before comparison.  The appropriate default port is used if none has been specified.  For URIs without a hostname there is significant variation between browsers, and you should not assume that any access will be available.
  
 Points to note: Points to note:
  
-It is the origin of the web page which counts, not the origin of the JavaScript (which might be different). +  * It is the origin of the web page which counts, not the origin of the JavaScript (which might be different). 
-Requests which cross subdomain boundaries do not satisfy the same-origin policy, even if the subdomains in question are located within the same administrative zone.+  Requests which cross subdomain boundaries do not satisfy the same-origin policy, even if the subdomains in question are located within the same administrative zone.
  
 Consequences of the same-origin policy are that web applications cannot easily combine data from multiple servers, or be served separately from any web services that they make use of.  This is problematic because there is often a need to separate these types of subsystem for security or performance reasons. An exception to the same-origin policy has therefore been defined, known as Cross-Origin Resource Sharing (CORS). Consequences of the same-origin policy are that web applications cannot easily combine data from multiple servers, or be served separately from any web services that they make use of.  This is problematic because there is often a need to separate these types of subsystem for security or performance reasons. An exception to the same-origin policy has therefore been defined, known as Cross-Origin Resource Sharing (CORS).
  
-CORS allows safe requests (such as GET and HEAD) to be made to any destination, but does not allow the script to see the result unless the server responds with a suitable Access-Control-Allow-Origin header. The same applies to some less-than-safe POST requests, which are allowed due to pre-existing loopholes. Other types of request are permitted, but are validated with the server before they are sent (a process known as preflight).+CORS allows safe requests (such as GET and HEAD) to be made to any destination, but does not allow the script to see the result unless the server responds with a suitable Access-Control-Allow-Origin header.  The same applies to some less-than-safe POST requests, which are allowed due to pre-existing loopholes.  Other types of request are permitted, but are validated with the server before they are sent (a process known as preflight).
  
 If CORS is unavailable then there are some alternative methods which can be used to circumvent the same-origin policy and achieve a similar outcome: If CORS is unavailable then there are some alternative methods which can be used to circumvent the same-origin policy and achieve a similar outcome:
  
-Install a reverse proxy between the browser and the relevant servers (or proxy the traffic through one of the servers), thereby making all necessary content accessible through a single domain name. Because this is a server-side solution it should work with any web browser. The main drawback is the additional traffic and latency, particularly if the servers are not physically colocated+  * Install a reverse proxy between the browser and the relevant servers (or proxy the traffic through one of the servers), thereby making all necessary content accessible through a single domain name. Because this is a server-side solution it should work with any web browser.  The main drawback is the additional traffic and latency, particularly if the servers are not physically co-located
-Use a <script> element to fetch data formatted as JSONP (which is similar to JSON, but has padding to invoke a callback function once the fetch is complete). This supports only GET requests, and compared to XMLHttpRequest is less satisfactory with regard to error handling and security, but provides much better compatibility with older browsers. +  Use a <script> element to fetch data formatted as JSONP [https://en.wikipedia.org/wiki/JSONP] (which is similar to JSON, but has padding to invoke a callback function once the fetch is complete).  This supports only GET requests, and compared to XMLHttpRequest is less satisfactory with regard to error handling and security, but provides much better compatibility with older browsers. 
-Programmatically populate and submit a <form> element. The response can be directed to an <iframe> in order to avoid reloading the page, but gaining access to the content may be problematic as this is subject to the same-origin policy. +  Programmatically populate and submit a <form> element.  The response can be directed to an <iframe> in order to avoid reloading the page, but gaining access to the content may be problematic as this is subject to the same-origin policy.
-Circumventing inappropriate response caching+
  
-If a web server outside your control fails to set appropriate cache control headers then it is usually possible to prevent caching by adding a dummy parameter with a random value to the query component of the URI. For example, the URI /folders/inbox might become /folders/inbox?dummy=a9e40717291db2f1.+==== Circumventing inappropriate response caching ====
  
-Avoid doing this unless necessary, as it can adversely affect performance due to cache pollution. It is better to provide correct cache control headers if you are able.+If a web server outside your control fails to set appropriate cache control headers then it is usually possible to prevent caching by adding a dummy parameter with a random value to the query component of the URI.  For example, the URI /folders/inbox might become /folders/inbox?dummy=a9e40717291db2f1.
  
-Variations+Avoid doing this unless necessary, as it can adversely affect performance due to cache pollution.  It is better to provide correct cache control headers if you are able.
  
-Reuse of XMLHttpRequest objects+===== Variations =====
  
-There is no objection to reusing an XMLHttpRequest object provided that there is no temporal overlap between requests, however you should not do this with the expectation of any significant performance gain: the effort required to create a new object is negligible in comparison to sending the HTTP request and processing the response. Furthermore you should not do this for requests which might otherwise be capable of executing in parallel, because having them share a single XMLHttpRequest instance would be likely to reduce performance.+==== Reuse of XMLHttpRequest objects ====
  
-An example where reuse makes good sense is in polling loop used to implement HTTP server pushThe requests naturally occur in series, so there should be no risk of contention. Howeverif an XMLHttpRequest object were needed for any other purpose in the same program then it would probably be best to use a separate one.+There is no objection to reusing an XMLHttpRequest object provided that there is no temporal overlap between requests, however you should not do this with the expectation of any significant performance gain: the effort required to create new object is negligible in comparison to sending the HTTP request and processing the response Furthermore you should not do this for requests which might otherwise be capable of executing in parallelbecause having them share a single XMLHttpRequest instance would be likely to reduce performance.
  
-Legacy support for Internet Explorer+An example where reuse makes good sense is in a polling loop used to implement HTTP server push.  The requests naturally occur in series, so there should be no risk of contention.  However, if an XMLHttpRequest object were needed for any other purpose in the same program then it would probably be best to use a separate one.
  
-Internet Explorer lacks native JavaScript support for XMLHttpRequest prior to IE7. It instead provides an ActiveX control named MSXML2.XMLHTTP with a similar API. Microsoft recommend using version 6.0 of this control if it is available, or failing that version 3.0, but not version 4.0 or 5.0. If none of these are available then Microsoft.XMLHTTP can be tried as a last resort. The native JavaScript class should always be the first preference:+==== Legacy support for Internet Explorer ====
  
 +Internet Explorer lacks native JavaScript support for XMLHttpRequest prior to IE7.  It instead provides an ActiveX control named MSXML2.XMLHTTP with a similar API. Microsoft recommend using version 6.0 of this control if it is available, or failing that version 3.0, but not version 4.0 or 5.0.  If none of these are available then Microsoft.XMLHTTP can be tried as a last resort. The native JavaScript class should always be the first preference:
 +
 +<code javascript>
 function createXMLHttpRequest() { function createXMLHttpRequest() {
   if (window.XMLHttpRequest) {   if (window.XMLHttpRequest) {
Line 291: Line 291:
   return null;   return null;
 } }
 +</code>
 +
 Further points to be aware of: Further points to be aware of:
  
-You may need to call open before registering the onreadystatechange handler. Normally this would make no difference, however open was originally conceived as a method for resetting the XMLHttpRequest object, and in the course of this resets the event handler. +  * You may need to call open before registering the onreadystatechange handler. Normally this would make no difference, however open was originally conceived as a method for resetting the XMLHttpRequest object, and in the course of this resets the event handler. 
-In testing it was found that Microsoft.XMLHTTP does not support the in operator (it causes an error which cannot be caught with an exception handler), and does not allow onreadystatechange to be set to null (but you can set it to a function that does nothing instead). +  In testing it was found that Microsoft.XMLHTTP does not support the in operator (it causes an error which cannot be caught with an exception handler), and does not allow onreadystatechange to be set to null (but you can set it to a function that does nothing instead). 
-Internet Explorer caches XMLHttpRequest responses, whereas most other browsers do not. This is not a bug, and it need not be a problem if you configure the web server to send appropriate cache control headers. You should do that regardless, because even if the browser does not cache the content then something else might. However, it has historically tended to be Internet Explorer usage which has caused this issue to manifest. +  Internet Explorer caches XMLHttpRequest responses, whereas most other browsers do not. This is not a bug, and it need not be a problem if you configure the web server to send appropriate cache control headers. You should do that regardless, because even if the browser does not cache the content then something else might. However, it has historically tended to be Internet Explorer usage which has caused this issue to manifest. 
-IE8 and IE9 do not support the JSON object in quirks mode. +  IE8 and IE9 do not support the JSON object in quirks mode.
-Alternatives+
  
-Using jQuery 
  
-jQuery provides several methods for performing HTTP requests, the most generic being jQuery.ajax which has broadly similar functionality to a raw XMLHttpRequest object. There are also a number of shorthand methods providing more specialised operations:+===== Alternatives ===== 
 + 
 +==== Using jQuery ==== 
 + 
 +jQuery provides several methods for performing HTTP requests, the most generic being jQuery.ajax which has broadly similar functionality to a raw XMLHttpRequest object.  There are also a number of shorthand methods providing more specialised operations: 
 + 
 +|jQuery.get|method = 'GET'
 +|jQuery.post|method = 'POST'
 +|jQuery.getJSON|method = 'GET'; dataType = 'json'
 +|jQuery.getScript|method = 'GET'; dataType = 'script'; execute script| 
 +|.load|method = 'GET'; dataType = 'html'; load HTML into element|
  
-jQuery.get method = 'GET' 
-jQuery.post method = 'POST' 
-jQuery.getJSON method = 'GET'; dataType = 'json' 
-jQuery.getScript method = 'GET'; dataType = 'script'; execute script 
-.load method = 'GET'; dataType = 'html'; load HTML into element 
 For example, given an empty <div> element with an id of inbox: For example, given an empty <div> element with an id of inbox:
  
 +<code javascript>
 <div id="inbox"/> <div id="inbox"/>
 +</code>
 +
 you could populate that element with pre-formatted HTML obtained from the URI /folders/inbox.html using .load: you could populate that element with pre-formatted HTML obtained from the URI /folders/inbox.html using .load:
  
 +<code javascript>
 $("#inbox").load("/folders/inbox.html"); $("#inbox").load("/folders/inbox.html");
-One of the main benefits of using jQuery is to abstract away differences between browsers. The 1.x branch provides support back to IE6.+</code>
  
-Using AngularJS+One of the main benefits of using jQuery is to abstract away differences between browsers.  The 1.x branch provides support back to IE6.
  
-AngularJS provides a service named $http for making HTTP requests. JSON-encoded responses are automatically detected and decoded. For example, the following code fragment would fetch and decode the webmail inbox content as per the scenario above:+==== Using AngularJS ====
  
 +AngularJS provides a service named $http for making HTTP requests.  JSON-encoded responses are automatically detected and decoded.  For example, the following code fragment would fetch and decode the webmail inbox content as per the scenario above:
 +
 +<code javascript>
 angular.module("webmail", []).controller("messages", function ($scope, $http) { angular.module("webmail", []).controller("messages", function ($scope, $http) {
  $http({method: "GET", url: "/folders/inbox"}).then(function (response) {  $http({method: "GET", url: "/folders/inbox"}).then(function (response) {
   $scope.messages = response.data;   $scope.messages = response.data;
  });  });
-});u +}); 
-The main benefit here is that the fetched data can be declaratively bound to page elements without the need to perform any explicit manipulation of the DOM. For example, to iterate over the inbox content and render it as an HTML table:+</code>
  
 +The main benefit here is that the fetched data can be declaratively bound to page elements without the need to perform any explicit manipulation of the DOM.  For example, to iterate over the inbox content and render it as an HTML table:
 +
 +<code javascript>
 <div ng-controller="messages"> <div ng-controller="messages">
  <table>  <table>
Line 336: Line 351:
  </table>  </table>
 </div> </div>
-Further Reading+</code> 
 + 
 + 
 +===== References ===== 
 + 
 +  * XMLHttpRequest Level 1, W3C Working Draft [http://www.w3.org/TR/XMLHttpRequest/]  
 +  * XMLHttpRequest, WHATWG Specification [https://xhr.spec.whatwg.org/
 +  * XMLHttpRequest, Web API Interfaces, Mozilla Developer Network [https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest] 
 +  * Using XMLHttpRequest, Web API Interfaces, Mozilla Developer Network [https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest] 
 +  * A Barth, The Web Origin Concept, RFC 6454, December 2011 [https://www.ietf.org/rfc/rfc6454.txt] 
  
-XMLHttpRequest Level 1, W3C Working Draft 
-XMLHttpRequest, WHATWG Specification 
-XMLHttpRequest, Web API Interfaces, Mozilla Developer Network 
-Using XMLHttpRequest, Web API Interfaces, Mozilla Developer Network 
-A Barth, The Web Origin Concept, RFC 6454, December 2011 
ajax/make_an_ajax_request_using_xmlhttprequest.1467632021.txt.gz · Last modified: 2020/07/15 09:30 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki