ajax:make_an_ajax_request_using_xmlhttprequest
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
ajax:make_an_ajax_request_using_xmlhttprequest [2016/07/04 11:33] – created peter | ajax: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, | Because the HTTP request occurs asynchronously, | ||
- | |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. | 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. | ||
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. | * Use cached credentials (such as cookies, or usernames and passwords for HTTP authentication) for sites that have been accessed using the same web browser. | ||
- | 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:// |
* 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. | + | Both the URI scheme and hostname are normalised to lower case before comparison. |
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. | + | |
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, | + | CORS allows safe requests (such as GET and HEAD) to be made to any destination, |
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 | + | * 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. |
- | Use a < | + | |
- | Programmatically populate and submit a < | + | |
- | 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 | + | ==== Circumventing inappropriate response |
- | Avoid doing this unless necessary, as it can adversely affect performance due to cache pollution. It is better to provide correct | + | If a web server outside your control fails to set appropriate |
- | Variations | + | Avoid doing this unless necessary, as it can adversely affect performance due to cache pollution. |
- | 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 | + | ==== Reuse of XMLHttpRequest |
- | An example where reuse makes good sense is in a polling loop used to implement | + | 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 |
- | Legacy support | + | 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. |
- | Internet Explorer lacks native JavaScript | + | ==== Legacy |
+ | 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; | ||
} | } | ||
+ | </ | ||
+ | |||
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). | + | |
- | 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. | + | |
- | 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. | ||
+ | |||
+ | |jQuery.get|method = ' | ||
+ | |jQuery.post|method = ' | ||
+ | |jQuery.getJSON|method = ' | ||
+ | |jQuery.getScript|method = ' | ||
+ | |.load|method = ' | ||
- | jQuery.get method = ' | ||
- | jQuery.post method = ' | ||
- | jQuery.getJSON method = ' | ||
- | jQuery.getScript method = ' | ||
- | .load method = ' | ||
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=" | <div id=" | ||
+ | </ | ||
+ | |||
you could populate that element with pre-formatted HTML obtained from the URI / | you could populate that element with pre-formatted HTML obtained from the URI / | ||
+ | <code javascript> | ||
$("# | $("# | ||
- | One of the main benefits of using jQuery is to abstract away differences between browsers. The 1.x branch provides support back to IE6. | + | </ |
- | Using AngularJS | + | One of the main benefits of using jQuery is to abstract away differences between browsers. |
- | AngularJS | + | ==== Using AngularJS |
+ | AngularJS provides a service named $http for making HTTP requests. | ||
+ | |||
+ | <code javascript> | ||
angular.module(" | angular.module(" | ||
| | ||
$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: | + | </ |
+ | 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=" | <div ng-controller=" | ||
< | < | ||
Line 336: | Line 351: | ||
</ | </ | ||
</ | </ | ||
- | Further Reading | + | </ |
+ | |||
+ | |||
+ | ===== References ===== | ||
+ | |||
+ | * XMLHttpRequest Level 1, W3C Working Draft [http:// | ||
+ | * XMLHttpRequest, | ||
+ | * XMLHttpRequest, | ||
+ | * Using XMLHttpRequest, | ||
+ | * A Barth, The Web Origin Concept, RFC 6454, December 2011 [https:// | ||
- | XMLHttpRequest Level 1, W3C Working Draft | ||
- | XMLHttpRequest, | ||
- | XMLHttpRequest, | ||
- | Using XMLHttpRequest, | ||
- | 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)