21.1 The XMLHttpRequest Object [Advanced JavaScript Programming 3rd Edition]

IE5 was the first browser to introduce XHR objects. In IE5, the XHR object is implemented through an ActiveX object in the MSXML library. Therefore, you may encounter three different versions of the XHR object in IE, namely MSXML2.XMLHttp, MSXML2.XMLHttp.3.0, and MXSML2.XMLHttp.6.0. To use the XHR objects in the MSXML library, write a function as discussed in Chapter 18 when creating XML documents, for example:

//For versions prior to IE7
function createXHR() {
	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) {
				//jump over
			}
		}
	}
	return new ActiveXObject(arguments.callee.activeXString);
}

This function will try to create the latest version of the XHR object based on the MSXML library available in IE.
IE7+, Firefox, Opera, Chrome and Safari all support native XHR objects. To create an XHR object in these browsers use the XMLHttpRequest constructor as shown below.

var xhr = new XMLHttpRequest();

If you only want to support IE7 and higher, then you can drop the function defined earlier and just use the native XHR implementation. However, if you must also support earlier versions of IE, you can add support for native XHR objects to the createXHR() function.

function createXHR() {
	if (typeof XMLHttpRequest != "undefined") {
		return new XMLHttpRequest();
	} else if (typeof ActiveXObject != "undefined") {
		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) {
					//jump over
				}
			}
		}
		return new ActiveXObject(arguments.callee.activeXString);
	} else {
		throw new Error("No XHR object available.");
	}
}

Running
the new code in this function first checks if the native XHR object exists, and returns a new instance of it if it does. If the native object does not exist, the ActiveX object is detected. If neither object exists, an error is thrown. Then, you can use the code below to create the XHR object in all browsers.

var xhr = createXHR();

Since the implementation of XHR in other browsers is compatible with the earliest IE implementation, the xhr object created above can be used in the same way in all browsers.

21.1.1 Usage of XHR

When using an XHR object, the first method to call is open(), which takes 3 parameters: the type of request to send ("get", "post", etc.), the URL of the request, and whether to send the request asynchronously or not boolean value of . The following is an example of calling this method.

xhr.open("get", "example.php", false);

This line of code will initiate a GET request to example.php. There are two points to note about this line of code: one is that the URL is relative to the current page where the code is executed (of course, an absolute path can also be used); the other is that calling the open() method does not actually send a request, but just starts a request to prepare send.

Requests can only be sent to URLs within the same domain using the same port and protocol. A security error is raised if the URL differs in any way from the page that initiated the request.

To send a specific request, the send() method must be called like this:

xhr.open("get", "example.txt", false);
xhr.send(null);

Run it
The send() method here receives one parameter, the data to be sent as the body of the request. If you do not need to send data through the request body, you must pass null, because this parameter is required for some browsers. After calling send(), the request is dispatched to the server.
Since this request is synchronous, the JavaScript code will wait until the server responds before continuing. After receiving the response, the data of the response will automatically populate the properties of the XHR object. The relevant properties are briefly described below.

  • responseText: The text to be returned as the response body.
  • responseXML: If the content-type of the response is "text/xml" or "application/xml", this attribute will hold the XML DOM document containing the response data.
  • status: The HTTP status of the response.
  • statusText: A description of the HTTP status.

After receiving the response, the first step is to check the status property to determine that the response has returned successfully. In general, an HTTP status code of 200 can be used as a sign of success. At this point, the content of the responseText property is ready, and with the correct content type, the responseXML should be accessible. In addition, a status code of 304 indicates that the requested resource has not been modified, and the cached version in the browser can be used directly; of course, it also means that the response is valid. To ensure an appropriate response is received, both of the above status codes should be checked as follows:

xhr.open("get", "example.txt", false);
xhr.send(null);
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
	alert(xhr.responseText);
} else {
	alert("Request was unsuccessful: " + xhr.status);
}

Run it
. Depending on the status code returned, this example may display what was returned by the server, or it may display an error message. We advise readers to check status to decide what to do next, rather than relying on statusText, which is less reliable for cross-browser use. Also, regardless of the content type, the content of the response body is saved to the responseText property; for non-XML data, the value of the responseXML property will be null.

Some browsers incorrectly report a 204 status code. The ActiveX version of XHR in IE will set 204 to 1223, while the native XHR in IE will normalize 204 to 200. Opera will report a status of 0 when it gets a 204.

There's certainly no problem with sending synchronous requests like this, but in most cases, we'll still send asynchronous requests to allow JavaScript to continue executing without waiting for a response. At this point, the readyState property of the XHR object can be detected, which represents the currently active stage of the request/response process. The possible values ​​for this property are as follows.

  • 0: Not initialized. The open() method has not been called.
  • 1: Start. The open() method has been called, but the send() method has not been called.
  • 2: Send. The send() method has been called, but no response has been received.
  • 3: Receive. Partial response data has been received.
  • 4: Done. All response data has been received and is ready to be used on the client side.

A readystatechange event is fired whenever the value of the readyState property changes from one value to another. You can use this event to detect the value of readyState after each state change. Typically, we are only interested in stages with a readyState value of 4, since all data is ready at this point. However, the onreadystatechange event handler must be specified before calling open() to ensure cross-browser compatibility. Let's look at an example.

var xhr = createXHR();
xhr.onreadystatechange = function() {
	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("get", "example.txt", true);
xhr.send(null);

Running it
The above code uses DOM level 0 methods to add event handlers to the XHR object because not all browsers support DOM level 2 methods. Unlike other event handlers, there is no event object passed to the onreadystatechange event handler; the XHR object itself must be used to determine what to do next.

This example uses the xhr object in the onreadystatechange event handler instead of the this object because of the scope of the onreadystatechange event handler. Using this object may cause the function to fail or cause an error to occur in some browsers. Therefore, using the actual XHR object instance variable is a more reliable approach.

In addition, the abort() method can also be called to cancel the asynchronous request before the response is received, as follows:

xhr.abort();

After calling this method, the XHR object stops firing events and no longer allows access to any response-related object properties. After terminating the request, the XHR object should also be dereferenced. Reusing XHR objects is not recommended for memory reasons.

21.1.2 HTTP header information

Every HTTP request and response comes with corresponding headers, some of which are useful to developers and some of which are not. The XHR object also provides methods for manipulating the information of these two headers (ie, request headers and response headers). By default, the following headers are also sent with an XHR request.

  • Accept: The type of content that the browser can handle.
  • Accept-Charset: The character set that the browser can display.
  • Accept-Encoding: The compression encoding that the browser can handle.
  • Accept-Language: The language currently set by the browser.
  • Connection: The type of connection between the browser and the server.
  • Cookies: Any cookies set by the current page.
  • Host: The domain where the requesting page resides.
  • Referer: The URI of the page that made the request. Note that the HTTP specification misspelled this header field, and to ensure compliance with the specification, it can only be wrong. (The correct spelling of this English word should be referrer.)
  • User-Agent: The browser's user agent string.

While the actual headers sent by different browsers will vary, the ones listed above are basically what all browsers send. Use the setRequestHeader() method to set custom request header information. This method accepts two parameters: the name of the header field and the value of the header field. To successfully send the request header information, setRequestHeader() must be called after calling the open() method and before calling the send() method, as shown in the following example.

var xhr = createXHR();
xhr.onreadystatechange = function() {
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("get", "example.php", true);
xhr.setRequestHeader("MyHeader", "MyValue");
xhr.send(null);

After the
server receives this custom header information, it can perform corresponding follow-up operations. We recommend readers to use custom header field names instead of field names normally sent by browsers, otherwise it may affect the server's response. Some browsers allow developers to override the default headers, but others do not.
Call the getResponseHeader() method of the XHR object and pass in the header field name to obtain the corresponding response header information. And call the getAllResponseHeaders() method to get a long string containing all header information. Take a look at the example below.

var myHeader = xhr.getResponseHeader("MyHeader");
var allHeaders = xhr.getAllResponseHeaders ();

On the server side, headers can also be used to send additional, structured data to the browser. In the absence of custom information, the getAllResponseHeaders() method typically returns multi-line text content like the following:

Date: Sun, 14 Nov 2004 18:04:03 GMT
Server: Apache/1.3.29 (Unix)
Vary: Accept
X-Powered-By: PHP/4.3.8
Connection: close
Content-Type: text/html; charset=iso-8859-1

This formatted output allows us to check the names of all header fields in the response without having to check for the existence of a field one by one.

21.1.3 GET Requests

GET is the most common type of request and is most often used to query the server for some information. When necessary, query string parameters can be appended to the end of the URL to send the information to the server. For XHR, the query string at the end of the URL passed to the open() method must be properly encoded.
A common mistake that occurs with GET requests is the wrong format of the query string. The name and value of each parameter in the query string must be encoded using encodeURIComponent() before being placed at the end of the URL; and all name-value pairs must be separated by an ampersand (&), as shown in the following example Show.

xhr.open("get", "example.php?name1=value1&name2=value2", true);

The following function can assist in adding query string parameters to the end of an existing URL:

function addURLParam(url, name, value) {
	url += (url.indexOf("?") == -1 ? "?": "&");
	url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
	return url;
}

The addURLParam() function accepts three parameters: the URL to which the parameter is to be added, the parameter's name, and the parameter's value. This function first checks whether the URL contains a question mark (to determine if any parameters already exist). If not, add a question mark; otherwise, add an ampersand. Then, the parameter name and value are encoded and added to the end of the URL. Finally, return the URL after adding parameters.
Below is an example of using this function to construct a request URL.

var url = "example.php";
//add parameters
url = addURLParam(url, "name", "Nicholas");
url = addURLParam(url, "book", "Professional JavaScript");
//initialize request
xhr.open("get", url, false);

Using the addURLParam() function here ensures that the query string is well-formed and reliably used for XHR objects.

21.1.4 POST requests

The second most frequently used after GET is the POST request, which is usually used to send data to the server that should be saved. A POST request should submit the data as the body of the request, which is traditionally not the case for a GET request. The body of a POST request can contain a very large amount of data in any format. A POST request can be initiated by passing "post" as the first parameter of the open() method, as shown in the following example.

xhr.open("post", "example.php", true);

The second step in sending a POST request is to pass some data to the send() method. Since XHR was originally designed primarily to process XML, XML DOM documents can be passed in here, and the incoming document will be serialized and submitted to the server as the body of the request. Of course, you can also pass in any string you want to send to the server here.
By default, the server does not treat POST requests and requests to submit Web forms equally. Therefore, there must be a program on the server side to read the raw data sent and parse out the useful parts from it. However, we can use XHR to mimic form submission: first set the Content-Type header to application/x-www-form-urlencoded, which is the content type of the form submission, and second create a string in the appropriate format . As discussed in Chapter 14, the format of the POST data is the same as the query string format. If you need to serialize the data from the form on the page before sending it to the server via XHR, you can use the serialize() function described in Chapter 14 to create this string:

function submitData() {
	var xhr = createXHR();
	xhr.onreadystatechange = function() {
		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);
	xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	var form = document.getElementById("user-info");
	xhr.send(serialize(form));
}

Run
this function to serialize the data in the form with ID "user-info" and send it to the server. The following example PHP file postexample.php can get the submitted data through $_POST:

<?php
header("Content-Type: text/plain");
echo <<<EOF
Name: {$_POST[‘user-name’]}
Email: {$_POST[‘user-email’]}
EOF;
?>

If the Content-Type header is not set, the data sent to the server will not appear in the $_POST superglobal. At this time, to access the same data, you must use $HTTP_RAW_POST_DATA.

POST requests consume more resources than GET requests. From a performance perspective, a GET request can be up to twice as fast as a POST request to send the same data.
wrote
Download the offline tutorial: http://www.shouce.ren/api/view/a/15218

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326680794&siteId=291194637