• bulletproof ajax: XMLHttpRequest


    ajax作者发表的论文:http://www.adaptivepath.com/ideas/ajax-new-approach-web-applications

    The Ajax Toolkit

    The XMLHttpRequest object is the engine that drives Ajax, but it doesn’t exist in a vacuum. As Jesse James Garrett said in his original essay, “Ajax isn’t  a technology. It’s really several technologies, each flourishing in its own right,
    coming together in powerful new ways.”

    ANY SERVER-SIDE LANGUAGE
      Chances are, you want your application to respond intelligently to a visitor’s  input. The server needs to be able to make decisions about what specific  information needs to be sent to the browser. In order to do that, you need to
    use some kind of programming language on the server.

    XML?
    You’d be forgiven for thinking that XML was a crucial component of Ajax applications.The term XMLHttpRequest itself, as well as its long-windedness, is  somewhat misleading.
    XML, which stands for eXtensible Markup Language, is a format for describing  data. Ajax applications require some kind of structured format to deliver  information from the server to the client. But XML is just one option. As we’ll
    see later on, there are other ways of structuring data that are equally viable for Ajax.

    注意:ajax不一定要用到xml

    Valid markup
    It’s entirely possible to build an Ajax application without using XML. But
    there is another kind of markup language that is fundamental to any Web
    site, with or without Ajax.
    HyperText Markup Language (HTML) is the lingua franca of the World Wide
    Web. It is used to give semantic structure to content on the Web. After the
    content itself, markup is the most important and valuable tool for creating
    Web pages.

    In some ways, it’s easier to explain what Ajax isn’t:
    Ajax is not a specific technology.
    ■ Ajax is not an acronym.
    Instead, Ajax is a methodology方法,理论。ajax不是一项技术,而是一项方法. It’s a way of working with a set of ingredients 组成部分,材料to create a more usable, responsive experience on the Web. Some of those ingredients are based on the server, but the majority are browser-based technologies:

    ajax组成:少部分基于server,大部分基于browser。
    ■ HTML or XHTML
    ■ CSS
    ■ DOM Scripting
    ■ XMLHttpRequest
    The XMLHttpRequest object is the glue that binds the server to the browser. Before looking at this mysterious object in more detail, it’s important to have  a good grounding in the Web Standards upon which Ajax is built.

    获取

    XMLHttpRequest对象
    function getHTTPObject() {
    var xhr = false;
    if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xhr;
    }

    It is still possible that the getHTTPObject function has returned a value of  false, meaning that the browser executing the script does not have Ajax  capabilities. If you explicitly check for this, you can make sure you won’t be
    asking older browsers to execute code beyond their ability:
    var request = getHTTPObject();
    if (request) {
    // do some Ajax
    }

    The getHTTPObject function works fine most of the time. But it does contain
    an assumption. Just because a browser supports ActiveX doesn’t necessarily
    mean that the specific ActiveX object for Ajax also exists.

    This is the case with Internet Explorer 5 for Mac. As it stands, the
    getHTTPObject function throws an error in that browser.
    One solution might be to look at the user-agent string of the browser and check
    its name and version number. This is called browser sniffing浏览器嗅探. It’s a very bad
    idea. User-agent strings can be spoofed哄骗, and browser sniffing inevitably triggers
    false positives. Object detection is always preferable to browser sniffing.
    In this particular case, you can use object detection to test only for the existence
    of ActiveX, not for a particular type of ActiveX object.

    最好的办法:

    function getHTTPObject() {
        var xhr = false;
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            try {
                    xhr = new ActiveXObject("Msxml2.XMLHTTP");
            }catch(e){
                try{
                    xhr=new ActiveXObject("Microsoft.XMLHTTP");
                }catch(e){
                    xhr=false;
                }
            }
        }
        return xhr;
    }

    onreadystatechange 事件由服务器触发。It is the handler for an event that istriggered not by the user, but by the server.

    During an Ajax operation, the server sends updates to the client about
    the current status of the communication. This is done by updating a property
    of the XMLHttpRequest object. The property is called readyState,
    which we’ll study in more detail later in this chapter. What interests us
    now is the fact that every time the readyState property is changed, the
    readystatechange event is triggered.

    Whenever the onreadystatechange event handler captures this event, it
    means something is happening on the server. Changing the readyState
    property is the server’s way of pinging the client.
    If you attach a function to the onreadystatechange event handler, that
    function will be executed every time the server pings the client with an
    update. Here’s an example:

    var request = getHTTPObject();
    if (request) {
    request.onreadystatechange = doSomething;
    }
    I’m assigning a reference to a function called doSomething to the
    onreadystatechange event handler. The doSomething function will be
    executed every time the readystatechange event is triggered.

    I’ve specified what I want to happen when the server sends an update to the
    client. I still need to specify exactly what I want from the server。

    Send a Request To a Server

     open(method,url,async)

    Specifies the type of request, the URL, and if the request should be handled asynchronously or not.

    method: the type of request: GET or POST
    url: the location of the file on the server
    async: true (asynchronous) or false (synchronous)

    url可以是绝对或相对路径。

    The file you are requesting must reside in the same domain as the JavaScript
    file that is making the request. (这点很重要)If the JavaScript file is being executed from
    foo.com, it cannot request a file from bar.com. Later on, I will show you some
    ways of getting around this security restriction, but for now, it’s best to think
    of XMLHttpRequest as being domain-specific.

    You can specify a Boolean value as the third argument for the open method.
    This indicates whether the request should occur asynchronously or not.
    If you specify a value of true, then the script will make an asynchronous
    request. This means it won’t wait for a response from the server before moving
    on to the rest of the script.
    If you specify a value of false, then the processing of the script will stop at
    that point. The script won’t resume until the Ajax request is completed.

    第3个参数基本上都是true。

    SEND
    The open method specifies the details of an Ajax request, but it doesn’t initiate
    the request.(open发生没有发送request) Use the send method to fire off a request that you have prepared
    using the open method.
    The send method takes a single argument. You can pass it a string of data
    that will then be sent to the server.
    If you are using the GET request method, don’t send any data. Instead, pass a
    value of null to the send method:
      request.send(null);

    If you need to send data to the server, use the POST request method. Send
    the data as a query string like this:
    name=Jeremy+Keith&message=Hello+world
      A query string is made up of name-value pairs joined by ampersands. Each
    name and value should be URL-encoded. That means spaces become plus
    signs and non-alphanumeric characters need to be encoded as hex values.
    The @ symbol becomes %40, for example.
    To send data, you need to use one more method of the XMLHttpRequest
    object.

    setRequestHeader
    When a Web browser requests a page from a Web server, it sends a series
    of headers along with the request. These headers are bits of metadata that
    describe the request. A header is used to declare whether a request is GET
    or POST.
    This ability to send headers can be reproduced in an Ajax request using a
    method called setRequestHeader. This method accepts two arguments

     setRequestHeader(header,value)

    If you are sending data to the server with a POST request, you need to set the
    value of the "Content-type" header to
    "application/x-www-form-urlencoded":
      request.setRequestHeader("Content-type", "application/
    x-www-form-urlencoded");
    This lets the server know that data is being sent, and that the data has been
    URL-encoded.

    A complete Ajax POST request looks like this:

    Receive a Response

    READYSTATE
    The readyState property indicates the current state of an Ajax request. Its
    value is numerical:
    ■ 0 Uninitialized. The open method hasn’t been called yet.
    ■ 1 Loading. The open method has been called, but the send method hasn’t.
    ■ 2 Loaded. The send method has been called. The request has begun.

    3 Interactive. The server is in the process of sending a response.
    ■ 4 Complete. The server has finished sending a response.

    Every time the value of readyState changes, the readystatechange event
    is triggered. If a function has been assigned to the onreadystatechange
    event handler, it will be executed every time readyState changes value。

    Rather than trying to do anything clever with the changing readyState property,
    it’s best just to wait until its value has reached 4. Then you know the
    server has finished sending a response.

    function doSomething() {
    if (request.readyState == 4) {
    // do something with the response
    }
    }

    The doSomething function will be executed more than once because it has
    been assigned to the onreadystatechange event handler:
    request.onreadystatechange = doSomething;
    Every time the readyState property changes, doSomething is executed,
    but the if statement in the function ensures that nothing will happen until
    readyState has a value of 4.

    STATUS
    In the same way that a Web browser sends headers with each request it makes,
    a Web server sends headers with each response it sends. (服务器发送的header信息)These headers contain
    information about the server, as well as information about the document
    being served. This information includes the document’s content type (HTML,
    XML, and so on) and character encoding (utf-8, iso-8859-1, and so on).
    The most important header sent with any response from a Web server is the
    status code. This three-digit numerical value, which the server sends with
    every response to a request, is part of the HyperText Transfer Protocol (HTTP)

    that drives all communication on the Web. I’m sure you’re familiar with the
    404 status code, which translates to “Not Found.” Some other codes are 403
    for “Forbidden,” and 500 for “Internal Server Error.”

    The most common status code is 200, which means “OK.” This code indicates
    that the server successfully sent the requested resource.
    In the XMLHttpRequest object, the status code sent by the server is available
    as a property called status. By comparing this property to a value of
    200, you can be sure that the server has sent a successful response

    function doSomething() {
    if (request.readyState == 4) {
    if (request.status == 200) {
    // the response was sent successfully
    }
    }
    }

    By adding an else clause, you can also deal with situations where everything
    doesn’t go according to plan:

    function doSomething() {
    if (request.readyState == 4) {
    if (request.status == 200) {
    // the response was sent successfully
    } else {
    // something went wrong!
    }
    }
    }

    200 isn’t the only server code that indicates a successful response. A value of
    304 translates as “Not Modified.” (304没修改)The server sometimes returns this response
    if a browser performs what’s known as a conditional GET request. The Opera
    browser uses conditional GET requests. In this situation, the server may return
    a response of 304, indicating that the document hasn’t changed since it was
    last requested, so the browser can safely use a cached version

    更好的函数:

    function doSomething() {
    if (request.readyState == 4) {
    if (request.status == 200 || request.status == 304) {
    // the response was sent successfully
    } else {
    // something went wrong!
    }
    }
    }

    RESPONSETEXT
    The responseText property of XMLHttpRequest contains the data sent
    from the server. It is a string. Depending on what the server is sending, this
    might be a string of HTML, a string of XML, or just a string of text.
    The complete responseText property is available when the readyState
    property reaches four, indicating that the Ajax request is complete:

    function doSomething() {
    if (request.readyState == 4) {
    if (request.status == 200 || request.status == 304) {
    alert(request.responseText);
    }
    }
    }

    RESPONSEXML
    If the server is sending back XML, then this data will be available in a property
    called responseXML. The responseXML property will be available only
    if the server sends the data with the correct headers.(responseXML当服务器发送了正确的header才可用) The MIME type must be text/xml.  In the next chapter, I will show you how to parse XML from the responseXML
    property.

    一个简单的实例:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script>
    function getHTTPObject() {
        var xhr = false;
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            try {
                    xhr = new ActiveXObject("Msxml2.XMLHTTP");
            }catch(e){
                try{
                    xhr=new ActiveXObject("Microsoft.XMLHTTP");
                }catch(e){
                    xhr=false;
                }
            }
        }
        return xhr;
    }
    
    
    function grabFile(file)
    {
         var request=getHTTPObject();
         if(request)
         {
             request.onreadystatechange = function() {
                    displayResponse(request);
             };
             request.open("GET", file, true);
             request.send(null);
         }
    }
    
    function displayResponse(request)
     {
         if(request.readyState==4)
         {
             if(request.status==200||request.status==304)
             {
                 alert(request.responseText);
             }
         }
     
    }
    
          
       </script>
    </head>
    
    <body>
    <body>
    <p>
    <a href="example.txt" onclick="grabFile(this.href); return false;">
    Click here to see the contents of a text file
    </a>
    </p>
    </body>
    </html>

    点击链接会输出文本内容。

  • 相关阅读:
    Qt学习之路,part1
    1.获取状态栏的高度
    如何在Android Studio中上传代码到Gitee上
    关于类图
    外观模式
    关于类的实例
    SharedPreference中关于editor.apply()和editor.commit()
    活动的4种启动模式
    unittest中case批量管理
    unittest使用
  • 原文地址:https://www.cnblogs.com/youxin/p/2661262.html
Copyright © 2020-2023  润新知