欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

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

系統(tǒng) 2245 0

上一篇文章 ,將jQuery.ajax中的一些細(xì)節(jié)補(bǔ)充完。這篇文章講解如果將類AJAX方法都包裝進(jìn)jQuery.ajax中。下篇文章則講解各預(yù)過濾器和分發(fā)器的細(xì)節(jié)。

?

為什么要包裝起來??

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

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

同理,JSON也無法通過XMLHttpRequest進(jìn)行跨域,所以利用Script DOM Element,將JSON填入一個(gè)回調(diào)函數(shù)中來實(shí)現(xiàn)其跨域,也就是JSONP(JSON with padding, 填充式JSON或參數(shù)式JSON)。

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

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

jQuery團(tuán)隊(duì)當(dāng)然希望開發(fā)者開發(fā)的時(shí)候,不需要想需不需要跨域,只要直接使用就行了。

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

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

而IE8也引入XDomainRequest也實(shí)現(xiàn)了CORS。

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

?

怎么包裝起來??

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

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

然后我們需要知道到底應(yīng)當(dāng)用那一套方案來執(zhí)行整個(gè)過程,所以我們需要一個(gè)分發(fā)機(jī)制( Transport )來得到最后的jqXHR對象。

?

inspectPrefiltersOrTransports

我們在jQuery.ajax找到了預(yù)過濾和分發(fā)機(jī)制的函數(shù),inspectPrefiltersOrTransports。

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


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

然后我們看看這個(gè)函數(shù)在干些什么。

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

    
      
      
        //
      
      
         定義個(gè)參數(shù)對象
      
      
        var
      
       inspected =
      
         {},
        
      
      
        //
      
      
         看看傳進(jìn)來的結(jié)構(gòu)體是prefilters, 還是transports
      
      
        //
      
      
         如果是prefilters,證明這是預(yù)過濾過程,如果是transports分發(fā)過程
      
      
        //
      
      
         所以這個(gè)是,是不是在分發(fā)過程
      
      
        seekingTransport = ( structure ===
      
         transports );

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

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

我們可以看到,這個(gè)函數(shù)實(shí)際上就是從prefilters和transports中取出對應(yīng)dataType的東東,然后過濾或者分發(fā)。

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

?

jQuery.ajaxPrefilter & jQuery.ajaxTransport

實(shí)際上,jQuery是通過這兩個(gè)接口來定義上面兩個(gè)對象的內(nèi)容的,一個(gè)是定義預(yù)過濾器,另一個(gè)則定義分發(fā)器。

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

而這兩個(gè)方法都是由addToPrefiltersOrTransports生成的。

?

addToPrefiltersOrTransports

      
        //
      
      
         jQuery.ajaxPrefilter和jQuery.ajaxTransport的構(gòu)造函數(shù)
      
      
        function
      
      
         addToPrefiltersOrTransports( structure ) {

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

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

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

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

接下來就是通過調(diào)用jQuery.ajaxPrefilter和jQuery.ajaxTransport方法,添加預(yù)過濾器和分發(fā)器來完成包裝。

?

?

?

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


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 天天碰天天操 | 91精品一区二区三区久久久久久 | 天天色综合天天 | 99国精产品一区二区三区A片 | 欧美国产一区二区 | 亚洲国产成人在线视频 | 国产精品久久久久久久久久免费 | 一区二区三区毛片 | 91香蕉视频在线看 | 日韩一区在线视频 | 操日日| 欧美黑人玩白人巨大极品 | 三级黄色一级视频 | 91麻豆一区二区 | 欧美第一区 | 天天干天天操 | 成人免费视频网站在线观看 | 婷婷综合久久狠狠色99h | 天天操你| 三级黄毛片 | 大伊香蕉精品视频在线天堂 | av网站观看 | 日韩视频在线观看免费 | 日韩中文字幕在线视频 | 丝袜美腿一区 | 国产免费一区 | 久久亚洲网 | 男人和女人做爰毛片试看 | 国产精品久久久久久久y | 自拍偷拍亚洲欧美 | 91在线一区二区 | 午夜黄色影院 | 男女在线无遮挡毛片免费 | 色欲AV色情国产又爽又色 | 国产福利视频 | 久久精品成人 | 一区二区三区免费在线观看 | 国产精品久久久久久久久久久久 | 日本私人色多多 | 無码一区中文字幕少妇熟女H | 色婷婷激情 |