zoukankan      html  css  js  c++  java
  • jQuery的ajax 简单解析与实现

    以下的内容只是个人的理解,技术有限,如有问题请指正(看得jq版本是1.3.2)

    jQuery的ajax, 就是我看的和理解,可以用在3个方面,一个是取一个script地址并执行一些操作 $jQuery.getScript; 一个是jsonp $jQuery.getJSON;还有一个就是一般的ajax应用了我主要记录的是jsonp 和 ajax 这方面的个人理解..

    jsonp

    我的理解是:
    创建一个全局的回调函数(假如是handler)
    在创建一个<script>标签,去请求一个服务器端的地址(假如是http://www.xxx.com, 写在script标签里面就是 http://www.xxx.com?callback=handler callback是跟别人约定好的,也可以不要callback 别人主要是通过这个约定好的callback取到 函数名 handler 然后返回一个可以执行的js)
    服务器端返回一个可以执行的js代码 (假如是 handler({name : "hello world"}))

    一个简单的例子

    上面的handler是 gg函数
    请求的地址是 http://active.zol.com.cn/guofeng/profile2.php?callback=gg


    截图为证




    返回的是




    页面上多了一段可以执行的script

    jQuery里面 有个默认配置
     
            ajaxSettings: {
                
    //url: location.href,
                global      : true,
                type        : 
    "GET",
                contentType : 
    "application/x-www-form-urlencoded",
                processData : 
    true,
                async       : 
    true,
                
    /*
                timeout: 0,
                data: null,
                username: null,
                password: null,
                
    */
                
    // Create the request object; Microsoft failed to properly
                // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
                // This function can be overriden by calling jQuery.ajaxSetup
                xhr:function(){
                    
    return window.ActiveXObject 
                        
    ? new ActiveXObject("Microsoft.XMLHTTP"
                        : 
    new XMLHttpRequest();
                },
                accepts: {
                    xml: 
    "application/xml, text/xml",
                    html: 
    "text/html",
                    script: 
    "text/javascript, application/javascript",
                    json: 
    "application/json, text/javascript",
                    text: 
    "text/plain",
                    _default: 
    "*/*"
                }
            }
    accepts 是设置请求头 accepts里面的配置项
     
     
    type 是提交类型
    async 是 是否异步 true 表示异步
    processData 是否修改data的结构 如果是true 表示修改
    ifModified  如果设置了这一项 就要设置http请求头里面的 If-Modified-Since 
    contentType 设置请求头contentType的类型
    application/xml;
    application/x-www-form-urlencoded
    application/json
     
    application/xml;
    参数传递用<xml>

    截图为证

     
     
    application/x-www-form-urlencoded
     参数传递用就是一般的字符串
    截图为证


    application/json
     参数传递是json形式的(cnblogs就是这样的形式)
    截图为证

     
     
    jquery.ajax的前部分主要是对jsonp 和 创建script 的处理
    jq的jsonp的用法是 callback=? 要以这种形式
    所以前面部分就是判断url 是不是这中形式 不是这中形式就转成这种形式 
    同时创建一个全局的变量当函数  回掉的时候执行该函数
     
    View Code
                //extend 的第一个参数为true 表示深度复制 
                //创建一个新的对象 jq.ajaxSettings全部copy过去 把s复制过去
                s = jq.extend(true, s, jq.extend(true, {}, jq.ajaxSettings, s));
                
    var jsonp,
                    
    // jsonp 的回调函数名字要以这种方式才行
                    jsre = /=\?(&|$)/g,
                    status,
                    data,
                    type 
    = s.type.toUpperCase();
                    
                
    //如果data不是字符串 转成字符串
                if ( s.data &&  typeof s.data !== "string" )
                    s.data 
    = jq.param(s.data);

                
    if ( s.dataType == "jsonp" ) {
                    
    if ( type == "GET" ) {
                        
    if ( !s.url.match(jsre) ){
                            
    //get 方式 参数都在url的后面
                            //如果没有=?这种形式 就转成这种形式  这是jq的jsonp形式  后面要把?变成函数名
                            //转成这种形式 http://www.xxx.com?callback=?
                            s.url += (s.url.match(/\?/? "&" : "?"+ (s.jsonp || "callback"+ "=?";                    
                        }
    //http://www.baidu.com?callback=?
                    } else if ( !s.data || !s.data.match(jsre) ){
                        
    //post方式 有专为存放参数的地方  这里是把参数和回调都转一下 
                        //形式 xx=xx&oo=oo.......&callback=?    
                        s.data = (s.data ? s.data + "&" : ""+ (s.jsonp || "callback"+ "=?";
                    }
                    s.dataType 
    = "json";
                }

                
    // url 符合 定义的jsonp形式 或者 s.data符合jsonp形式
                if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
                    
    // 这里的jsonp 就是后面的可执行函数的 函数名了
                    jsonp = "jsonp" + jsc++;
                    
                    
    // Replace the =? sequence both in the query string and the data
                    // /=\?(&|$)/g
                    //将 ? 转 成函数名字
                    if ( s.data )
                        s.data 
    = (s.data + "").replace(jsre, "=" + jsonp + "$1");
                    s.url 
    = s.url.replace(jsre, "=" + jsonp + "$1");
                    s.dataType 
    = "script";
        
                    
    // 定义全局的函数名了 后面请求完毕后就会执行这个函数
                    window[ jsonp ] = function(tmp){
                        data 
    = tmp;
                        success();
                        
    //complete();
                        // Garbage collect
                        window[ jsonp ] = undefined;
                        
    trydelete window[ jsonp ]; } catch(e){}
                        
    if ( head )
                            head.removeChild( script );
                    };
                }

                
    if ( s.dataType == "script" && s.cache == null )
                    s.cache 
    = false;
        
                
    /*if ( s.cache === false && type == "GET" ) {
                    var ts = now();
                    // try replacing _= if it is there
                    //alert(s.url)  http://www.baidu.com?callback=jsonp1315980993828
                    var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");

                    // if nothing was replaced, add timestamp to the end
                    s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
                }
    */
                
    // If data is available, append data to url for get requests
                if ( s.data && type == "GET" ) {
                    
    //加上其他的参数
                    s.url += (s.url.match(/\?/? "&" : "?"+ s.data;
        
                    
    // IE likes to send both get and post data, prevent this
                    //ie的 get post 都会传送s.data   好像就是这个意思  所以节省开支
                    s.data = null;
                }
                
                
    // Watch for a new set of requests
                //if ( s.global && ! jQuery.active++ )
                //    jQuery.event.trigger( "ajaxStart" );
        
                
    // Matches an absolute URL, and saves the domain
                //取url的 前面的信息 和 域名
                var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
                
                
    if ( s.dataType == "script" && type == "GET" && parts
                
    && ( parts[1&& parts[1!= location.protocol || parts[2!= location.host )){
                    
    var head = document.getElementsByTagName("head")[0];
                    
    var script = document.createElement("script");
                    script.src 
    = s.url;
                    
    if (s.scriptCharset)
                        script.charset 
    = s.scriptCharset;
        
                    
    //如果不是jsonp方式  就是创建一个script标签
                    if ( !jsonp ) {
                        
    //保证回调函数只执行一次
                        var done = false;
        
                        
    // Attach handlers for all browsers  兼容所有的浏览器的写法
                        script.onload = script.onreadystatechange = function(){
                            
    if ( !done && (!this.readyState ||
                                    
    this.readyState == "loaded" || this.readyState == "complete") ) {
                                done 
    = true;
                                
    //success();
                                //complete();

                                
    // Handle memory leak in IE  jq里面可以说反复的强调了 删除元素时 该dom元素引用的对象要断开引用  不然会内存泄露
                                script.onload = script.onreadystatechange = null;
                                head.removeChild( script );
                            }
                        };
                    }    
                    head.appendChild(script);    
                    
    // We handle everything using the script element injection
                    return undefined;
                }
     
     
    jQuery.ajax 的后面的部分就是处理ajax的了
    jq有专门的设置请求头的部分
    其中的   If-Modified-Since 比较重要了
    jq里面用 jquery.lastModified 来保存最后的修改时间的
    形式是 jquery.lastModified[url] = 时间
    按我的理解是 
    我发送一次请求后  服务器看在 If-Modified-Since  里面的时间后有没有做修改,没有做修改返回304 读缓存的文件 有做修改返回200
    这么做的好处是可以节约网络资源咯
     
    jq1.3.2里面是设置的定时器 去判断请求是否已经完成
    onreadystatechange是定时器去执行的函数
    如果设置了s.timeout
    会在这个时间后去查看是否已经xhr的状态  是否已经完成了回调  如果没有 abort 终止掉请求
     
    jq还有一些方法配合 ajajx
    jquery.httpSuccess
    jquery.httpNotModified
    jquery.httpData
     
    jquery.httpSuccess
    判断请求是否已经成功了
    jquery.httpNotModified
    判断 服务器那边是否已经做过了修改
    jquery.httpData
    因为返回的数据是根据请求头的content-type来的,所以要对不同的数据做处理
    因为返回的数据是根据请求头的content-type来的,所以要对不同的数据做处理
    在这里 又对 xml script  json 的处理
    其中script 用到了jquery.globalEval
     
    一个完整的例子
  • 相关阅读:
    http://www.cnblogs.com/fengyin/archive/2011/01/18/1938628.html 前端优化
    iframe中子父窗口互调的js方法
    Mydomain操作说明
    Struts中出现DispatchMapping[***] does not define a handler property 的解决办法
    MyEclipse 不编译了,无论怎么更改保存, classes目录下都是空的.
    checkstyle配置文件说明
    SQLite学习手册(数据类型)
    动态加载datagrid控件的一个问题
    sharepoint
    VS.net 的一个bug
  • 原文地址:https://www.cnblogs.com/wtcsy/p/2177770.html
Copyright © 2011-2022 走看看