亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

jQuery ajax —— 將類AJAX方法包裝起來

系統 2116 0

上一篇文章 ,將jQuery.ajax中的一些細節補充完。這篇文章講解如果將類AJAX方法都包裝進jQuery.ajax中。下篇文章則講解各預過濾器和分發器的細節。

?

為什么要包裝起來??

我們知道,古老的XMLHttpRequest出于同源策略考慮,是不支持跨域的。所以,在前端想動態加載跨域Javascript腳本,通常是使用被稱為Script DOM Element的方案,如:

      
        var
      
       scriptElem = document.createElement("script"
      
        );
scriptElem.src 
      
      = "http://anydomain.com/A.js"
      
        ;
document.getElementsByTagName(
      
      "head")[0].appendChild(scriptElem);
    

同理,JSON也無法通過XMLHttpRequest進行跨域,所以利用Script DOM Element,將JSON填入一個回調函數中來實現其跨域,也就是JSONP(JSON with padding, 填充式JSON或參數式JSON)。

實際上JSONP就是將,得到JSON后回調的函數通過GET傳參告訴服務器,然后服務器拼接一段腳本,用該回調函數并參數為需要的JSON數據,如:

      callback({ "name": "Justany_WhiteSnow" });
    

jQuery團隊當然希望開發者開發的時候,不需要想需不需要跨域,只要直接使用就行了。

所以他們把XMLHttpRequest、Script DOM Element、JSONP包裝起來,都當成AJAX來使用。

這里順便提一下,其實現代瀏覽器(Firefox 3.5+、Safari 4+、Chrome等)中,通過XMLHttpRequeest實現了CORS(Cross-Origin Resource Sharing, 跨源資源共享)原生支持。也就是XMLHttpRequest在某些瀏覽器中,實際上是可以跨域的,只需要設置一下HTTP Response Header中的Access-Control-Allow-Origin。比如設置成通配符*。

而IE8也引入XDomainRequest也實現了CORS。

但畢竟某些瀏覽器不行,所以,咳咳……這不能成為一種通用方案。

?

怎么包裝起來??

首先我們有一個山寨XHR對象,也就是jqXHR對象。通過對其添加 send、 abort來模擬XHR對象。

可是我們需要在不同方案執行前先處理一下特異性的東東,所以我們需要一個預過濾機制( Prefilter )來預先處理一下。

然后我們需要知道到底應當用那一套方案來執行整個過程,所以我們需要一個分發機制( Transport )來得到最后的jqXHR對象。

?

inspectPrefiltersOrTransports

我們在jQuery.ajax找到了預過濾和分發機制的函數,inspectPrefiltersOrTransports。

      
        //
      
      
         預過濾
      
      
        inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );


      
      
        //
      
      
        ……
      
      
        //
      
      
         得到transport
      
      
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
    

然后我們看看這個函數在干些什么。

      
        //
      
      
         檢測函數,預過濾或者分發器
      
      
        function
      
      
         inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {

    
      
      
        //
      
      
         定義個參數對象
      
      
        var
      
       inspected =
      
         {},
        
      
      
        //
      
      
         看看傳進來的結構體是prefilters, 還是transports
      
      
        //
      
      
         如果是prefilters,證明這是預過濾過程,如果是transports分發過程
      
      
        //
      
      
         所以這個是,是不是在分發過程
      
      
        seekingTransport = ( structure ===
      
         transports );

    
      
      
        function
      
      
         inspect( dataType ) {
        
      
      
        var
      
      
         selected;
        
      
      
        //
      
      
         將inspected的dataType對應屬性設置成true
      
      
        inspected[ dataType ] = 
      
        true
      
      
        ;
        
      
      
        //
      
      
         遍歷prefilters對應dataType對象中的所有過濾器或者轉換器工廠函數
      
      
        jQuery.each( structure[ dataType ] || [], 
      
        function
      
      
        ( _, prefilterOrFactory ) {
            
      
      
        //
      
      
         得到dataType或者轉換器
      
      
        var
      
       dataTypeOrTransport =
      
         prefilterOrFactory( options, originalOptions, jqXHR );
            
      
      
        //
      
      
         如果dataType為字符串,即上面過程是過濾器
      
      
        //
      
      
         如果在預過濾過程
      
      
        //
      
      
         并且這個過濾出來的dataType不等于剛開始傳進來的dataType
      
      
        if
      
      ( 
      
        typeof
      
       dataTypeOrTransport === "string" && !seekingTransport && !
      
        inspected[ dataTypeOrTransport ] ) {
                
      
      
        //
      
      
         將現在這個新的dataType插入到options中
      
      
                        options.dataTypes.unshift( dataTypeOrTransport );
                
      
      
        //
      
      
         檢測新的dataType
      
      
                        inspect( dataTypeOrTransport );
                
      
      
        return
      
      
        false
      
      
        ;
            
      
      
        //
      
      
         否則如果在分發過程
      
      
            } 
      
        else
      
      
        if
      
      
         ( seekingTransport ) {
                
      
      
        //
      
      
         定義selected為dataTypeOrTransport
      
      
        return
      
       !( selected =
      
         dataTypeOrTransport );
            }
        });
        
        
      
      
        return
      
      
         selected;
    }

    
      
      
        //
      
      
         檢查dataTypes數組的第一個,如果結果是undefined,
      
      
        //
      
      
         則看看上面檢查的是不是通配符*,如果不是則檢查通配符
      
      
        return
      
       inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*"
      
         );
}
      
    

我們可以看到,這個函數實際上就是從prefilters和transports中取出對應dataType的東東,然后過濾或者分發。

那么怎么定義prefilters和transports這兩個對象的呢?

?

jQuery.ajaxPrefilter & jQuery.ajaxTransport

實際上,jQuery是通過這兩個接口來定義上面兩個對象的內容的,一個是定義預過濾器,另一個則定義分發器。

      jQuery.ajaxPrefilter =
      
         addToPrefiltersOrTransports( prefilters );
jQuery.ajaxTransport 
      
      = addToPrefiltersOrTransports( transports );
    

而這兩個方法都是由addToPrefiltersOrTransports生成的。

?

addToPrefiltersOrTransports

      
        //
      
      
         jQuery.ajaxPrefilter和jQuery.ajaxTransport的構造函數
      
      
        function
      
      
         addToPrefiltersOrTransports( structure ) {

    
      
      
        //
      
      
         dataTypeExpression是可選參數,缺省值為*
      
      
        return
      
      
        function
      
      
        ( dataTypeExpression, func ) {
        
        
      
      
        //
      
      
         如果dataTypeExpression不是字符串
      
      
        //
      
      
         模擬重載
      
      
        if
      
       ( 
      
        typeof
      
       dataTypeExpression !== "string"
      
         ) {
            func 
      
      =
      
         dataTypeExpression;
            
      
      
        //
      
      
         缺省為*
      
      
            dataTypeExpression = "*"
      
        ;
        }

        
      
      
        var
      
      
         dataType,
            i 
      
      = 0
      
        ,
            
      
      
        //
      
      
         將dataTypeExpression轉為小寫,并用空白拆成數組
      
      
            dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) ||
      
         [];

        
      
      
        //
      
      
         如果func是一個函數
      
      
        if
      
      
         ( jQuery.isFunction( func ) ) {
            
      
      
        //
      
      
         遍歷dataTypeExpression中的所有dataType
      
      
        while
      
       ( (dataType = dataTypes[i++
      
        ]) ) {
                
      
      
        //
      
      
         如果有必要則刪除頭部的+號
      
      
        if
      
       ( dataType[0] === "+"
      
         ) {
                    
      
      
        //
      
      
         刪除+號
      
      
                    dataType = dataType.slice( 1 ) || "*"
      
        ;
                    
      
      
        //
      
      
         往structure對應的dataType中推入func函數
      
      
                    (structure[ dataType ] = structure[ dataType ] ||
      
         []).unshift( func );

                
      
      
        //
      
      
         否則不需要處理
      
      
                } 
      
        else
      
      
         {
                    
      
      
        //
      
      
         往structure對應的dataType中推入func函數
      
      
                    (structure[ dataType ] = structure[ dataType ] ||
      
         []).push( func );
                }
            }
        }
    };
}
      
    

接下來就是通過調用jQuery.ajaxPrefilter和jQuery.ajaxTransport方法,添加預過濾器和分發器來完成包裝。

?

?

?

jQuery ajax —— 將類AJAX方法包裝起來


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美久久xxxxxx影院 | 九色蝌蚪自拍 | 国产免费爱在线观看视频 | www.深夜| 久久一区二区精品 | 国产成人成人一区二区 | 亚洲精品亚洲人成在线 | 911国产在线观看精品 | 免费又爽又黄禁片视频在线播放 | 国产女人体一区二区三区 | 九九热伊人 | 久久亚洲私人国产精品va | 色偷偷青青草原在线视频 | 伊人首页 | 欧美专区在线 | 久久影| 五月天婷婷免费视频 | 日日摸日日 | 久久久久免费精品国产小说 | 日日日夜夜操 | 香蕉在线影院 | 婷婷色站 | 亚洲国产一区在线 | 亚洲视频第二页 | 欧美日韩第二页 | 国产精品婷婷久久爽一下 | 中文字幕日韩女同互慰视频 | 视频一区二区三区在线观看 | 午夜国产精品色福利视频 | 日韩欧美色视频 | 伊人伊色 | 997在线观看视频国产 | 久久亚洲国产午夜精品理论片 | 久99re视频9在线观看 | 麻豆久久婷婷综合五月国产 | 欧美日韩亚洲一区二区三区 | 国产福利专区精品视频 | 一区二区三区四区视频在线 | 天天爽影院一区二区在线影院 | 色偷偷亚洲天堂 | 日本一级大黄毛片免费基地 |