zoukankan      html  css  js  c++  java
  • 精通javascript:ajax使用

    数据串行化:

    要发送一系列的数据到服务器上,第一步要整理他的格式,使服务器易于读取,这一过程称为“串行化”。串行化有2种不同的情况,但都能满足多种不同的传输需求。

    1.传输一个常规的js对象,其中可能包含键/值(值可能是字符串或数字)

    2.从一系列的表单的输入栏中提交。这种情况和第一种情况的不同之处在于提交的元素要按顺序排列,而第一个情况可以任意排列.

    // A simple object holding key/value pairs
    {
        name: "John",
        last: "Resig",
        city: "Cambridge",
        zip: 02140
    }
    
    // Serialized form
    name=John&last=Resig&city=Cambridge&zip=02140
    
    // Another set of data, with multiple values
    [
        { name: "name", value: "John" },
        { name: "last", value: "Resig" },
        { name: "lang", value: "JavaScript" },
        { name: "lang", value: "Perl" },
        { name: "lang", value: "Java" }
    ]
    
    // And the serialized form of that data
    name=John&last=Resig&lang=JavaScript&lang=Perl&lang=Java
    
    // Finally, lets find some input elements (using the id() method that
    // we made in the DOM chapter)
    [
        id( "name" ),
        id( "last" ),
        id( "username" ),
        id( "password" )
    ]
    
    // And serialize them into a data string
    name=John&last=Resig&username=jeresig&password=test

    下面我们建立一个将上面的数据结构串行化的标准方法。下面的函数可以对大多数表单元素进行串行化,不过多选按钮除外。

    // Serialize a set of data. It can take two different types of objects:
    //  - An array of input elements.
    //  - A hash of key/value pairs
    // The function returns a serialized string
    function serialize(a) {
        // The set of serialize results
        var s = [];
            
        // If an array was passed in, assume that it is an array
        // of form elements
        if ( a.constructor == Array ) {
    
            // Serialize the form elements
            for ( var i = 0; i < a.length; i++ )
                s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );
                
        // Otherwise, assume that it's an object of key/value pairs
        } else {
    
            // Serialize the key/values
            for ( var j in a )
                s.push( j + "=" + encodeURIComponent( a[j] ) );
    
        }
            
        // Return the resulting serialization
        return s.join("&");
    }
    encodeURIComponent转义字符串组件

    建立一个能够完整处理ajax请求的函数:
    1.处理错误
    成功响应代码:状态码在200到300之间的属于成功的请求
    未修改响应码:Not modified 304
    本地存储的文件:如果你在本机上之间执行ajax应用程序,而不通过web服务器,就算请求成功了,也不会得到任何返回的状态码。者意味着,在执行本地文件请求且得不到状态码时,你应该把这种情况算做成功的响应。
    safari与未修改状态
    如果文档自上次请求(或者通过浏览器明确发送一个if modified since首部,指定上次修改过的时间给服务器)未曾修改过,safari返回的状态码会是undefined。这是一个比较怪异的情形,也让人难以调试。
    // Check to see if an XMLHttpRequest object has a 'Success' state, or not.
    // The function takes one argument, the XMLHttpRequest object
    function httpSuccess(r) {
        try {
            // If no server status is provided, and we're actually 
            // requesting a local file, then it was successful
            return !r.status && location.protocol == "file:" ||
    
                // Any status in the 200 range is good
                ( r.status >= 200 && r.status < 300 ) ||
    
                // Successful if the document has not been modified
                r.status == 304 ||
    
                // Safari returns an empty status if the file has not been modified
                navigator.userAgent.indexOf("Safari") >= 0 && typeof r.status == "undefined";
        } catch(e){}
    
        // If checking the status failed, then assume that the request failed too
        return false;
    }

    检查http响应的成功状态是非常重要的一部,不做检查可能导致许多难以预料的结果,比如服务器返回的其实是html的错误页面,而非xml温度。

     我们把这个函数集成在完整的ajax方案中。

    2.检查超时。

     在XMLHttpRequest的默认实现中缺乏的另一个有用的功能是如何判断请求超时。

     我们可以利用setTimeout()来完成这个功能:

    // Create the request object
    var xml = new XMLHttpRequest();
    
    // Open the asynchronous POST request
    xml.open("GET", "/some/url.cgi", true);
    
    // We're going to wait for a request for 5 seconds, before giving up
    var timeoutLength = 5000;
    
    // Keep track of when the request has been succesfully completed
    var requestDone = false;
    
    // Initalize a callback which will fire 5 seconds from now, cancelling
    // the request (if it has not already occurred).
    setTimeout(function(){
        requestDone = true;
    }, timeoutLength);
    
    // Watch for when the state of the document gets updated
    xml.onreadystatechange = function(){
        // Wait until the data is fully loaded,
        // and make sure that the request hasn't already timed out
        if ( xml.readyState == 4 && !requestDone ) {
    
            // xml.responseXML contains the XML Document (if one was returned)
            // xml.responseText contains the response text (if no XML document was provided)
    
            // Clean up after ourselves, to avoid memory leaks
            xml = null;
        }
    };
    
    // Establish the connection to the server
    xml.send();

    3处理响应的数据

     responseXML,如果服务器返回的是xml温度,必须明确指定其内容首部(content header)是‘Content-type:text/xml",这一点才起作用

    // A function for extracting data from an HTTP reponse
    // It takes two arguments, the XMLHttpRequest object and
    // An optional argument – the type of data that you're expecting from the server
    // Correct values include: xml, script, text, or html – the default is "", which
    // determines what the data type is based upon the content-type header
    function httpData(r, type) {
        // Get the content-type header
        var ct = r.getResponseHeader("content-type");
    
        // If no default type was provided, determine if some
        // form of XML was returned from the server
        var data = !type && ct && ct.indexOf("xml") >= 0;
    
        // Get the XML Document object if XML was returned from
        // the server, otherwise return the text contents returned by the server
        data = type == "xml" || data ? r.responseXML : r.responseText;
    
        // If the specified type is "script", execute the returned text
        // response as if it was JavaScript
        if ( type == "script" )
            eval.call( window, data );
    
        // Return the response data (either an XML Document or a text string)
        return data;
    }

    完整的ajax程序包

    // A generic function for performming AJAX requests
    // It takes one argument, which is an object that contains a set of options
    // All of which are outline in the comments, below
    function ajax( options ) {
    
        // Load the options object with defaults, if no
        // values were provided by the user
        options = {
            // The type of HTTP Request
            type: options.type || "POST",
    
            // The URL the request will be made to
            url: options.url || "",
    
            // How long to wait before considering the request to be a timeout
            timeout: options.timeout || 5000,
    
            // Functions to call when the request fails, succeeds,
            // or completes (either fail or succeed)
            onComplete: options.onComplete || function(){},
            onError: options.onError || function(){},
            onSuccess: options.onSuccess || function(){},
    
            // The data type that'll be returned from the server
            // the default is simply to determine what data was returned from the
            // and act accordingly.
            data: options.data || ""
        };
    
        // Create the request object
        var xml = new XMLHttpRequest();
    
        // Open the asynchronous POST request
        xml.open("GET", "/some/url.cgi", true);
    
        // We're going to wait for a request for 5 seconds, before giving up
        var timeoutLength = 5000;
    
        // Keep track of when the request has been succesfully completed
        var requestDone = false;
    
        // Initalize a callback which will fire 5 seconds from now, cancelling
        // the request (if it has not already occurred).
        setTimeout(function(){
             requestDone = true;
        }, timeoutLength);
    
        // Watch for when the state of the document gets updated
        xml.onreadystatechange = function(){
            // Wait until the data is fully loaded,
            // and make sure that the request hasn't already timed out
            if ( xml.readyState == 4 && !requestDone ) {
    
                // Check to see if the request was successful
                if ( httpSuccess( xml ) ) {
    
                    // Execute the success callback with the data returned from the server
                    options.onSuccess( httpData( xml, options.type ) );//我们把返回的data传给了函数的参数
    
                // Otherwise, an error occurred, so execute the error callback
                } else {
                    options.onError();
                }
    
                // Call the completion callback
                options.onComplete();
    
                // Clean up after ourselves, to avoid memory leaks
                xml = null;
            }
        };
    
        // Establish the connection to the server
        xml.send();
    
        // Determine the success of the HTTP response
        function httpSuccess(r) {
            try {
                // If no server status is provided, and we're actually 
                // requesting a local file, then it was successful
                return !r.status && location.protocol == "file:" ||
    
                    // Any status in the 200 range is good
                    ( r.status >= 200 && r.status < 300 ) ||
    
                    // Successful if the document has not been modified
                    r.status == 304 ||
    
                    // Safari returns an empty status if the file has not been modified
                    navigator.userAgent.indexOf("Safari") >= 0 && typeof r.status == "undefined";
            } catch(e){}
    
            // If checking the status failed, then assume that the request failed too
            return false;
        }
    
        // Extract the correct data from the HTTP response
        function httpData(r,type) {
            // Get the content-type header
            var ct = r.getResponseHeader("content-type");
    
            // If no default type was provided, determine if some
            // form of XML was returned from the server
            var data = !type && ct && ct.indexOf("xml") >= 0;
    
            // Get the XML Document object if XML was returned from
            // the server, otherwise return the text contents returned by the server
            data = type == "xml" || data ? r.responseXML : r.responseText;
    
            // If the specified type is "script", execute the returned text
            // response as if it was JavaScript
            if ( type == "script" )
                eval.call( window, data );
    
            // Return the response data (either an XML Document or a text string)
            return data;
        }
    
    }



  • 相关阅读:
    浅析如何保证vuex中的state动态添加属性的响应式及解决deep watch / computed监听vuex state对象属性变化不生效的问题
    浅析security遇到java.lang.IllegalArgumentException:Cannot pass null or empty values to constructor问题处理
    Java AES加解密报错javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher的问题原因及2种解决方式
    浅析Vue3中如何通过vmodel实现父子组件的双向数据绑定及利用computed简化父子组件双向绑定
    浅析pdfbox将pdf文件转图片报错Cannot read JPEG2000 image的问题及JPEG与JPEG2000介绍了解
    浅析Vue3中vuex的基本使用、模块化及如何使用mapState/mapGetters和mapActions
    浅析Object.assign()基本用法(对象合并、同名属性覆盖、仅1个参数时直接返回、target不是对象会转成对象、源对象位置为非对象时不同的处理规则字符串的特殊情况、拷贝的属性限制)及需要注意的点(浅拷贝、同名属性替换、数组的处理把索引当属性替换、取值函数先取值再拷贝)和常见应用(给对象添加属性、合并多个对象、给属性设置默认值)
    浅析setup如何通过ref获取子组件实例中的DOM结构/数据/方法及获取子组件实例数据都是空的处理(defineExpose API 的使用)、Vue3模板引用refs、在组合式API中使用template refs、for循环中如何获取及重置refs、如何监听模板引用
    解决uniapp ios播放本地视频不显示controls的问题、uniapp video开始播放如何设置默认全屏
    Deep learning:三十四(用NN实现数据的降维)
  • 原文地址:https://www.cnblogs.com/youxin/p/2741849.html
Copyright © 2011-2022 走看看