掌握 Ajax,第 3 部分: Advanced requests and responses in Ajax
2006-03-14 15:37
393 查看
Mastering Ajax, Part 3: Advanced requests and responses in AjaxGain a complete understanding of HTTP status codes, ready states, and the XMLHttpRequest object |
| |||||||||||
Discuss | |||||||||||
Sample code |
New site feature |
|
Rate this page |
|
<!--
if (document.referrer&&document.referrer!="") {
// document.write(document.referrer);
var q = document.referrer;
var engine = q;
var isG = engine.search(/google/.com/i);
var searchTerms;
//var searchTermsForDisplay;
if (isG != -1) {
var i = q.search(/q=/);
var q2 = q.substring(i+2);
var j = q2.search(/&/);
j = (j == -1)?q2.length:j;
searchTerms = q.substring(i+2,i+2+j);
if (searchTerms.length != 0) {
searchQuery(searchTerms);
document.write("<div id=/"contents/"></div>");
}
}
}
//-->
</script>
In the last
135f1
article in this series, I provided a solid introduction to the
XMLHttpRequestobject, the centerpiece of an Ajax application that handles requests to a server-side application or script, and also deals with return data from that server-side component. Every Ajax application uses the
XMLHttpRequestobject, so you'll want to be intimately familiar with it to make your Ajax applications perform and perform well.In this article, I move beyond the basics in the last article and concentrate on more detail about three key parts of this request object:The HTTP ready stateThe HTTP status codeThe types of requests that you can makeEach of these is generally considered part of the plumbing of a request; as a result, little detail is recorded about these subjects. However, you will need to be fluent in ready states, status codes, and requests if you want to do more than just dabble in Ajax programming. When something goes wrong in your application -- and things always go wrong -- understanding ready states, how to make a HEAD request, or what a 400 status code means can make the difference between five minutes of debugging and five hours of frustration and confusion.
|
XMLHttpRequestobject has a property called
readyState. This property ensures that a server has completed a request and typically, a callback function uses the data from the server to update a Web form or page. Listing 1 shows a simple example of this (also in the last article in this series -- see Resources).Listing 1. Deal with a server's response in a callback function
open()).1: The request is set up, but not sent (before you've called
send()).2: The request was sent and is in process (you can usually get content headers from the response at this point).3: The request is in process; often some partial data is available from the response, but the server isn't finished with its response.4: The response is complete; you can get the server's response and use it.If you want to go beyond the basics of Ajax programming, you need to know not only these states, but when they occur and how you can use them. First and foremost, you need to learn at what state of a request you encounter each ready state. Unfortunately, this is fairly non-intuitive and also involves a few special cases.Ready states in hidingThe first ready state, signified by the
readyStateproperty 0 (
readyState == 0), represents an uninitialized request. As soon as you call
open()on your request object, this property is set to 1. Because you almost always call
open()as soon as you initialize your request, it's rare to see
readyState == 0. Furthermore, the uninitialized ready state is pretty useless in practical applications.Still, in the interest of being complete, check out Listing 2 which shows how to get the ready state when it's set to 0.Listing 2. Get a 0 ready state
getSalesData()is the function that your Web page calls to start a request (like when a button is clicked). Note that you've got to check the ready state before
open()is called. Figure 1 shows the result of running this application.Figure 1. A ready state of 0
|
open()hasn't been called. The only use for this ready state in almost-real-world Ajax programming is if you make multiple requests using the same
XMLHttpRequestobject across multiple functions. In that (rather unusual) situation, you might want to ensure that a request object is in an uninitialized state (
readyState == 0) before making a new requests. This essentially ensures that another function isn't using the object at the same time.Viewing an in-progress request's ready stateAside from the 0 ready state, your request object should go through each of the other ready states in a typical request and response, and finally end up with a ready state of 4. That's when the
if (request.readyState == 4)line of code you see in most callback functions comes in; it ensures the server is done and it's safe to update a Web page or take action based on data from the server.It is a trivial task to actually see this process as it takes place. Instead of only running code in your callback if the ready state is 4, just output the ready state every time that your callback is called. For an example of code that does this, check out Listing 3.Listing 3. Check the ready state
updatePage(); to do this, set the
onreadystatechangeproperty of your request object to
updatePage().This code is a great illustration of exactly what
onreadystatechangemeans -- every time the request's ready state changes,
updatePage()is called and you see an alert. Figure 2 shows a sample of this function being called, in this case with a ready state of 1.Figure 2. A ready state of 1Try this code yourself. Put it into your Web page and then activate your event handler (click a button, tab out of a field, or use whatever method you set up to trigger a request). Your callback function will run several times -- each time the ready state of the request changes -- and you'll see an alert for each ready state. This is the best way to follow a request through each of its stages.Browser inconsistenciesOnce you've a basic understanding of this process, try to access your Web page from several different browsers. You should notice some inconsistencies in how these ready states are handled. For example, in Firefox 1.5, you see the following ready states:1234This shouldn't be a surprise since each stage of a request is represented here. However, if you access the same application using Safari, you should see -- or rather, not see -- something interesting. Here are the states you see on Safari 2.0.1:234Safari actually leaves out the first ready state and there's no sensible explanation as to why; it's simply the way Safari works. It also illustrates an important point: While it's a good idea to ensure the ready state of a request is 4 before using data from the server, writing code that depends on each interim ready state is a sure way to get different results on different browsers.For example, when using Opera 8.5, things are even worse with displayed ready states:34Last but not least, Internet Explorer responds with the following states:1234If you have trouble with a request, this is the very first place to look for problems. Add an alert to show you the request's ready state so you can ensure that things are operating normally. Better yet, test on both Internet Explorer and Firefox -- you'll get all four ready states and be able to check each stage of the request.Next I look at the response side.Response data under the microscopeOnce you understand the various ready states that occur during a request, you're ready to look at another important piece of the
XMLHttpRequestobject -- the
responseTextproperty. Remember from the last article that this is the property used to get data from the server. Once a server has finished processing a request, it places any data that is needed to respond to the request back in the
responseTextof the request. Then, your callback function can use that data, as seen in Listing 1 and Listing 4.Listing 4. Use the response from the server
responseTextproperty.Viewing the response text during a requestLike the ready state, the value of the
responseTextproperty changes throughout the request's life cycle. To see this in action, use code like that shown in Listing 5 to test the response text of a request, as well as its ready state.Listing 5. Test the responseText property
responseTextproperty is undefined (see Figure 3); you'd see an error if the JavaScript console was open as well.Figure 3. Response text with a ready state of 2At ready state 3 though, the server has placed a value in the
responseTextproperty, at least in this example (see Figure 4).Figure 4. Response text with a ready state of 3You'll find that your responses in ready state 3 vary from script to script, server to server, and browser to browser. Still, this is remains incredibly helpful in debugging your application.Getting safe dataAll of the documentation and specifications insist that it's only when the ready state is 4 that data is safe to use. Trust me, you'll rarely find a case where the data cannot be obtained from the
responseTextproperty when the ready state is 3. However, to rely on that in your application is a bad idea -- the one time you write code that depends on complete data at ready state 3 is almost guaranteed to be the time the data is incomplete.A better idea is to provide some feedback to the user that when the ready state is 3, a response is forthcoming. While using a function like
alert()is obviously a bad idea -- using Ajax and then blocking the user with an alert dialog box is pretty counterintuitive -- you could update a field on your form or page as the ready state changes. For example, try to set the width of a progress indicator to 25 percent for a ready state of 1, 50 percent for a ready state of 2, 75 percent for a ready state of 3, and 100 percent (complete) when the ready state is 4.Of course, as you've seen, this approach is clever but browser-dependent. On Opera, you'll never get those first two ready states and Safari drops the first one (1). For that reason, I'll leave code like this as an exercise rather than include it in this article.Time to take a look at status codes.A closer look at HTTP status codesWith ready states and the server's response in your bag of Ajax programming techniques, you're ready to add another level of sophistication to your Ajax applications -- working with HTTP status codes. These codes are nothing new to Ajax. They've been around on the Web for as long as there has been a Web. You've probably already seen several of these through your Web browser:401: Unauthorized403: Forbidden404: Not FoundYou can find more (for a complete list, see Resources). To add another layer of control and responsiveness (and particularly more robust error-handling) to your Ajax applications, then you need to check the status codes in a request and respond appropriately.200: Everything is OKIn many Ajax applications, you'll see a callback function that checks for a ready state and then goes on to work with the data from the server response, as in Listing 6.Listing 6. Callback function that ignores the status code
statusproperty of the
XMLHttpRequestobject. To make sure that not only did the server finish with a request but that it also reported an OK status, add an additional check in your callback function as shown in Listing 7.Listing 7. Check for a valid status code
|
XMLHttpRequestobject, consider this one last stop -- add HEAD requests to your repertoire. In the previous two articles, I showed you how to make GET requests; in an upcoming article, you'll learn all about sending data to the server using POST requests. In the spirit of enhanced error handling and information gathering, though, you should learn how to make HEAD requests.Making the requestActually making a HEAD request is quite trivial; you simply call the
open()method with "HEAD" instead of "GET" or "POST" as the first parameter, as shown in Listing 9.Listing 9. Make a HEAD request with Ajax
getResponseHeader()method on the
XMLHttpRequestobject. So to get the length of a response, just call
request.getResponseHeader("Content-Length");. To get the content type, use
request.getResponseHeader("Content-Type");.In many applications, making HEAD requests adds no functionality and might even slow down a request (by forcing a HEAD request to get data about the response and then a subsequent GET or POST request to actually get the response). However, in the event that you are unsure about a script or server-side component, a HEAD request can allow you to get some basic data without dealing with response data or needing the bandwidth to send that response.In conclusionFor many Ajax and Web programmers, the material in this article seems fairly advanced. What is the value in making a HEAD request? What is really a case where you should handle a redirection status code explicitly in your JavaScript? These are good questions; for simple applications, the answer is that these advanced techniques are unlikely to be valuable.However, the Web is no longer a place where simple applications are tolerated; users have become more advanced, customers expect robustness and advanced error reporting, and managers are fired because an application goes down 1 percent of the time.It's your job then, to go beyond a simple application and that requires a more thorough understanding of
XMLHttpRequest.If you can account for the various ready states -- and understand how they differ from browser to browser -- you'll be able to debug an application quickly. You might even come up with creative functionality based on a ready status and report on a request's status to users and customers.If you have a handle on status codes, you can set your application up to deal with a script's errors, unexpected responses, and edge cases. As a result, your application will work all of the time, rather than just in the situation where everything goes exactly right.Add to this the ability to make HEAD requests, check for the existence of a URL, and find out when a file was modified, and you can ensure that users get valid pages, are up-to-date on their information, and (most importantly) surprise them with just how robust and versatile your application is.This article isn't going to make your applications flashy, help you highlight text with fading yellow spotlights, or feel more like a desktop. While these are all strengths of Ajax (and topics we'll cover in subsequent articles), they are to some degree just icing on the cake. If you can use Ajax to build a solid foundation in which your application handles errors and problems smoothly, users will return to your site and application. Add to this the visual trickery that I'll talk about in upcoming articles and you'll have thrilled, excited, and happy customers. (Seriously, you don't want to miss the next article!)
相关文章推荐
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握Ajax - 第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- [转]掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应[IBM]
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应
- 掌握 Ajax,第 3 部分: Ajax 中的高级请求和响应