Ajax and Comet
Ajax (short for Asynchronous JavaScript + XML)You can request data from the server without detaching (refresh) the page to bring a better user experience.
The core of Ajax technology is the XMLHttpRequest object (XHR ).
I. XMLHttpRequest object
/* Compatible with earlier IE versions */function createXHR () {if (typeof XMLHttpRequest! = "Undefined") {return new XMLHttpRequest ();} else if (typeof ActiveXObject! = "Undefined") {// applicable to versions earlier than IE7 if (typeof arguments. callee. activeXString! = "String") {var versions = ["MSXML2.XMLHttp. 6.0 "," MSXML2.XMLHttp. 3.0 "," MSXML2.XMLHttp "], I, len; for (I = 0, len = versions. length; I <len; I ++) {try {new ActiveXObject (versions [I]); arguments. callee. activeXString = versions [I]; break;} catch (ex) {// skip} return new ActiveXObject (arguments. callee. activeXString);} If neither else {// XHR object nor ActiveX object exists, throw the throw new Error ("No XHR object available. ");}}
1. XHR usage
Xhr. open ("request type get | post, etc.", "request URL", "whether to send requests asynchronously ");
Note:
(1) relative to the current page on which the code is executed, the URL can also use an absolute path)
(2) The open () method does not actually send a request, but simply starts a request for sending.
Xhr. send ("data sent by the request body ");
Note:
(1) If you do not need to send data (such as get requests) through the request body, null must be passed in, because this parameter is required for Some browsers.
(2) After sending () is called, the request will be distributed to the server.
Supplement: The xhr. open () method is "false", that is, synchronous requests. The JavaScript code will continue to be executed after the server responds. Otherwise, the subsequent code will continue to be executed.
After receiving the server response, the corresponding data is automatically filled with the XHR object attributes.
ResponseText: response body returned text responseXML: If the response content type is "text/xml" or "application/xml ", this attribute stores the xml dom Document status: HTTP status statusText of the response data.
// To ensure that the appropriate response is received: 200: Successful; 304: the resource is not modified if (xhr. status >=200 & xhr. status <300) | xhr. status = 304) {console. log (xhr. responseText );}
Description:
(1) Some browsers may report a success status code of 204 with errors
(2) Whatever the content type, the content of the response body is saved to the responseText attribute. For XML data, responseXML is also assigned a value; otherwise, the value is null.
For asynchronous requests, you can check the readyState attribute of the XHR object. This attribute indicates the current active phase of the Request/response process.
0: not initialized. Open () method 1 has not been called: Start. The open () method has been called, but the send () method 2 has not been called: send. The send () method has been called, but no response has been received. 3: receive. Partially received response data 4: complete. All response data has been received and can be used on the client.
When the value of the readyState attribute changesReadystatechangeEvent. This event can be used to detect the status changesReadyState. However,You must specify the onreadystatechange event handler before calling open () to ensure cross-browser compatibility.
Var xhr = createXHR (); xhr. onreadystatechange = function (event) {// do not use this, And the scope may be faulty. if (xhr. readyState = 4) {if (xhr. status >=200 & xhr. status <300) | xhr. status = 304) {console. log (xhr. responseText);} else {console. log ("Request was unsuccessful:" + xhr. status) ;}}; xhr. open ("get", "example.txt", true); xhr. send (null );
Before receiving the response data, you can call the abort () method to cancel the asynchronous request:
Xhr. abort (); xhr = null; // release the reference and release the memory.
2. HTTP header information
SetRequestHeader (): Set custom request header information. It must be called after the open () method is called and before the send () method is called.
GetResponseHeader () getAllResponseHeaders (): You can obtain the specified (all) response header information.
var xhr = createXHR(); xhr.onreadystatechange = function(){};xhr.open("get", "example.php", true);xhr.setRequestHeader("MyHeader", "MyValue");xhr.send(null);
3. GET request
Open ()The query string at the end of the URL of the method must be properly encoded.
function addURLParam(url, name, value) { url += (url.indexOf("?") == -1 ? "?" : "&"); url += encodeURIComponent(name) + "=" + encodeURIComponent(value); return url;}var url = "http://test.com";url = addURLParam(url, "uid" , 5);url = addURLParam(url, "siteid", 123); // "http://test.com?uid=5&siteid=123"xhr.open("get", url, true);xhr.send(null);
4. POST request
POST requests use data as the request body
/* Serialized form */function serialize (form) {var parts = new Array (); var field = null; for (var I = 0, len = form. elements. length; I <len; I ++) {field = form. elements [I]; switch (field. type) {case "select-one": case "select-multiple": for (var j = 0, optLen = field. options. length; j <optLen; j ++) {var option = field. options [j]; if (option. selected) {var optValue = ""; if (option. hasAttribute) {optValue = (opti On. hasAttribute ("value ")? Option. value: option. text);} else {optValue = (option. attributes ["value"]. specified? Option. value: option. text);} parts. push (encodeURIComponent (field. name) + "=" + encodeURIComponent (optValue) ;}} break; case undefined: // fieldset case "file": // file input case "submit ": // submit button case "reset": // reset button case "button": // custom button break; case "radio": // radio button case "checkbox ": // checkbox if (! Field. checked) {break;}/* falls through */default: parts. push (encodeURIComponent (field. name) + "=" + encodeURIComponent (field. value);} return parts. join ("&");}
/* Send the request */function submitData () {var xhr = createXHR (); xhr. onreadystatechange = function (event) {if (xhr. readyState = 4) {if (xhr. status >=200 & xhr. status <300) | xhr. status = 304) {alert (xhr. responseText);} else {alert ("Request was unsuccessful:" + xhr. status) ;}}; xhr. open ("post", "postexample. php ", true); // content type of form submission xhr. setRequestHeader ("Content-Type", "application/x-www-form-urlencoded"); var form = document. getElementById ("user-info"); // The Request body is data xhr. send (serialize (form ));}
Ii. XMLHttpRequest Level 2
XMLHttpRequest Level 1 describes the implementation details of existing XHR objects. XMLHttpRequest Level 2 further develops XHR. Not all browsers fully implement the XMLHttpRequest Level 2 specification, but all browsers implement part of it.
1. FormData
// Create the FormData object var data = new FormData (); data. append ("name", "ligang ");
// Fill xhr with form elements. open ("post", "postexample. php ", true); var form = document. getElementById ("user-info"); // The convenience of using FormData is that you do not need to explicitly set the request header on the XHR object. // Xhr. setRequestHeader ("Content-Type", "application/x-www-form-urlencoded"); xhr. send (new FormData (form ));
2. timeout settings
IE8 adds a timeout attribute to the XHR object, indicating the number of milliseconds after the request is responded.
xhr.open("get", "timeout.php", true);xhr.timeout = 60 * 1000;xhr.ontimeout = function(){ alert("Request did not return in a second.");}; xhr.send(null);
Compatibility with other browsers
Xhr. open ("get", "timeout. php ", true); xhr. onreadystatechange = function (event) {if (xhr. readyState = 4) {// clear the timer clearTimeout (timeout); if (xhr. status >=200 & xhr. status <300) | xhr. status = 304) {console. log (xhr. responseText);} else {console. log ("Request was unsuccessful:" + xhr. status) ;}}; // set the timeout time to 1 minute var timeout = setTimeout (function () {xmlHttpRequest. abort (); xmlHttpRequest = null ;}, 60*1000); xmlHttpRequest. send (null );
3. overrideMimeType () method
Override the MIME type of the XHR response,It must be before the send () method.
If the MIME type returned by the server is text/plain, but the data actually contains XML. The responseXML attribute is still null Based on the MIME type. In this caseOverrideMimeType ()Method to ensure that the response is processed as XML rather than plain text (that is, the responseXML is assigned a value ).
var xhr = createXHR();xhr.open("get", "text.php", true);xhr.overrideMimeType("text/xml");xhr.send(null);
Iii. Progress events
Six progress events:
Loadstart: triggered when the first byte of the response data is received. Progress: continuously triggered during response receiving. Error: triggered when a request error occurs. Abort: triggered when the abort () method is called and terminated. Load: triggered when the complete response data is received. Loadend: triggered after communication is completed or an error, abort, or load event is triggered.
1. load event
It can replace readystatechagne events. Its handler receives an event object, and its target attribute points to the XHR object instance, so that it can access all the methods and attributes of the XHR object. However, not all browsers implement event objects.
2. progress event
Its handler receives an event object, and its target attribute points to the XHR object instance, but it contains three additional attributes.
LengthComputable: A boolean position that indicates whether progress information is available. position: the number of received bytes. totalSize: The expected number of bytes determined based on the content-length response header.
Note::
It must be added before calling the open () method
Var xhr = createXHR (); xhr. onload = function (event) {// event.tar get has compatibility issues, so you can only use xhr if (xhr. status >=200 & xhr. status <300) | xhr. status = 304) {console. log (xhr. responseText);} else {console. log ("Request was unsuccessful:" + xhr. status) ;}}; xhr. onprogress = function (event) {var divStatus = document. getElementById ("status"); if (event. lengthComputable) {divStatus. innerHTML = "Received" + event. position + "of" + event. totalSize + "bytes" ;}}; xhr. open ("get", "altevents. php ", true); xhr. send (null );
4. Cross-source Resource Sharing
CORS (Cross-Origin Resource Sharing)The basic idea behind it is to use a custom HTTP header to allow the browser to communicate with the server, so as to determine whether the request or response should succeed or fail.
When a request is sent, an additional Origin header is appended to it, which contains the source information (protocol, domain name, and port) of the Request page ), this allows the server to determine whether to respond based on the header information.
Origin: http://www.test.com
If the service deems this request acceptable, the same source information will be sent back in the Access-Control-Allow-Origin header (if it is a public resource, you can send it back "*").
Access-Control-Allow-Origin: http://www.test.com
Note:: The request and response do not contain cookie information.
1. CORS: XDR (XDomainRequest) is implemented in IE. All XDR requests are asynchronous and cannot be created. The method is similar to XHR. 2. Implementation of CORS by other browsers: native support for CORS is achieved through the XMLHttpRequest object. You only need to input an absolute address to the open () method. Supports synchronous requests.
Cross-origin XHR object security restrictions:
(1) You cannot use setRequestHeader () to set a custom header.
(2) You cannot send or receive cookies.
(3) The getAllResponseHeaders () method always returns an empty string.
Suggestions: To access local resources, it is best to use relative URLs; to access remote resources, use absolute URLs.
3. cross-browser CORS
Function createCORSRequest (method, url) {var xhr = new XMLHttpRequest (); if ("withCredentials" in xhr) {// check whether XHR supports CORS in a simple way, check whether the withCredentials attribute xhr exists. open (method, url, true);} else if (typeof XDomainRequest! = "Undefined") {// ie xdr xhr = new XDomainRequest (); xhr. open (method, url);} else {xhr = null;} return xhr;} var request = createCORSRequest ("get", "http://www.somewhere-else.com/xdr.php"); if (request) {request. onload = function () {// do something with request. responseText}; request. send ();}
V. Other cross-origin Technologies
With the ability of DOM to execute cross-origin requests, a request can also be sent without relying on XHR objects, and the server code does not need to be modified.
1. Image Ping
Tags, which can load images from any web page without the need to focus on cross-origin. This is also the main way for advertising to track page views.
Image Ping is a simple and unidirectional Cross-Domain Communication Method with servers. The browser cannot obtain any specific data. However, by listening to load and error events, you can know when the response was received.
var img = new Image();img.onload = img.error = function() { console.log("Done!");};img.src = "http://www.test.com/getImage?id=1";
Disadvantages:
(1) only Get requests can be sent.
(2) unable to access server response text
2. JSONP (JSON with padding)
It consists of a callback function and data.
The callback function is the function that should be called on the page when the response arrives. The return function name is generally specified in the request. The data is the JSON data in the callback function.
JSONP uses dynamic <script>
Element to use
function handleResponse(response){ alert("You're at IP address " + response.ip + ", which is in " + response.city + ", " + response.region_name);}var script = document.createElement("script");script.src = "http://freegeoip.net/json/?callback=handleResponse";document.body.insertBefore(script, document.body.firstChild);
Advantages: Can directly access the response text and support two-way communication between the browser and the server.
Disadvantages:
(1) JSONP loads code execution from other domains, and its security cannot be ensured.
(2) It is difficult to determine whether the JSONP request fails.
3. Comet
With more advanced Ajax technology, servers push data to pages.
There are two ways to implement Comet: Long polling and stream.
(1) Long polling: The page initiates a request to the server, and the server keeps the connection open until data can be sent. After the data is sent, the browser closes the connection and then initiates a new request to the server. [Difference: For short polling, the server sends a response immediately, regardless of whether it is valid or not. For long polling, the server waits for a response to be sent .]
(2) HTTP stream: Only one HTTP connection is used in the lifecycle. The browser sends a request to the server, while the server keeps the connection open and periodically sends data to the browser.
/*** Progress: the function called when receiving data * finished: The function called when the connection is closed */function createStreamingClient (url, progress, finished) {var xhr = new XMLHttpRequest (), received = 0; xhr. open ("get", url, true); xhr. onreadystatechange = function () {var result; if (xhr. readyState = 3) {// get only the new data and adjust counter result = xhr. responseText. substring (received); received + = result. length; // call the progress callback Progress (result);} else if (xhr. readyState = 4) {finished (xhr. responseText) ;}}; xhr. send (null); return xhr;} var client = createStreamingClient ("streaming. php ", function (data) {alert (" stored ed: "+ data) ;}, function (data) {alert (" Done! ");});
Server send event: SSE and event stream
4. Web Sockets
The goal is to provide full duplex and bidirectional communication on a single persistent connection.
Advantage: it can send a very small amount of data between the client and the server, without worrying about the bytes overhead of HTTP.
Disadvantage: Protocol preparation takes longer than JavaScript API preparation.
// You Must input absolute URLvar socket = new WebSocket ("ws: // www.example.com/server.php") to the WebSocket constructor; // send data to the server (only plain text can be sent, other data needs to be serialized) socket. send ("Hello"); // receives the response data socket from the server. onmessage = function (event) {var data = event. data ;};
Other events:
Open: triggered when the connection is established successfully. Error: When an error occurs, the connection cannot be sustained. Close: triggered when the connection is closed.
Note:: The WebSocket object does not support DOM Level 2 event listeners. You must use DOM level 0 syntax to define each event.
</Script>