九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
jquery.ajax
  • 這所有的最終都是通過jQuery.ajax()來完成的。   
  • ajax : function(s) {   
  •     //兩次繼承s,以便在測試中能檢測   
  •     s = jQuery.extend(true, s, jQuery.extend(true, {},    
  • jQuery.ajaxSettings,    s));         ①   
  •     var jsonp, jsre = /=\?(&|$)/g, status, data,   
  •  type = s.type  .toUpperCase();   
  • // 如果不是字符集串就轉(zhuǎn)換在查詢字符集串   
  • if (s.data && s.processData && typeof s.data != "string")   
  •         s.data = jQuery.param(s.data);   
  •   
  • // 構(gòu)建jsonp請求字符集串。jsonp是跨域請求,要加上callback=?后面將會加函數(shù)名   
  • if (s.dataType == "jsonp") {                               ②   
  • if (type == "GET") {//使get的url包含 callback=?后面將會進行加函數(shù)名   
  •         if (!s.url.match(jsre))   
  •             s.url += (s.url.match(/\?/) ? "&" : "?")   
  •                             + (s.jsonp || "callback") + "=?";   
  •             } // 構(gòu)建新的s.data,使其包含callback=function name   
  • else if (!s.data || !s.data.match(jsre))   
  •         s.data = (s.data ? s.data + "&" : "") + (s.jsonp||"callback")+ "=?";   
  • s.dataType = "json";   
  • }          
  • //判斷是否為jsonp,如果是,進行處理。   
  • if (s.dataType == "json"     
  •             && (s.data && s.data.match(jsre) || s.url.match(jsre))) {③   
  •      jsonp = "jsonp" + jsc++;   
  • / /為請求字符集串的callback=加上生成回調(diào)函數(shù)名   
  •     if (s.data)s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");   
  •     s.url = s.url.replace(jsre, "=" + jsonp + "$1");   
  •   
  •             // 我們需要保證jsonp 類型響應(yīng)能正確地執(zhí)行   
  •     //jsonp的類型必須為script。這樣才能執(zhí)行服務(wù)器返回的   
  •     //代碼。這里就是調(diào)用這個回調(diào)函數(shù)。   
  •     s.dataType = "script";   
  • //window下注冊一個jsonp回調(diào)函數(shù)有,讓ajax請求返回的代碼調(diào)用執(zhí)行它,   
  •     //在服務(wù)器端我們生成的代碼 如callbackname(data);形式傳入data.   
  •     window[jsonp] = function(tmp) {   
  •         data = tmp;success();complete();   
  •     // 垃圾回收,釋放聯(lián)變量,刪除jsonp的對象,除去head中加的script元素   
  •        window[jsonp] = undefined;   
  •         try {   delete window[jsonp];   
  •             } catch (e) {   }   
  •         if (head)   head.removeChild(script);   
  •         };   
  •     }   
  •   
  • if (s.dataType == "script" && s.cache == null)  s.cache = false;   
  • // 加上時間戳,可見加cache:false就會加上時間戳   
  • if (s.cache === false && type == "GET") {   
  •     var ts = now();   
  •     var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");   
  •     // 沒有代替,就追加在url的尾部   
  •     s.url = ret+ ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_="  
  •                         + ts : "");   
  •     }   
  • // data有效,追加到get類型的url上去   
  • if (s.data && type == "GET") {   
  •         s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;   
  •         // 防止IE會重復(fù)發(fā)送get和post data   
  •         s.data = null;   
  •         }   
  • // 監(jiān)聽一個新的請求   
  • if (s.global && !jQuery.active++) jQuery.event.trigger("ajaxStart");④   
  • // 監(jiān)聽一個絕對的url,和保存domain   
  • var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec(s.url);   
  • // 如果我們正在請求一個遠程文檔和正在load json或script通過get類型   
  • //location是window的屬性,通過和地址欄中的地址比較判斷是不是跨域。   
  • if (s.dataType == "script"  && type == "GET"&& parts    && (parts[1] &&    
  • parts[1] != location.protocol || parts[2] != location.host)) {⑤   
  •         // 在head中加上<script src=""></script>   
  •         var head = document.getElementsByTagName("head")[0];   
  •         var script = document.createElement("script");   
  •         script.src = s.url;   
  •         if (s.scriptCharset)    script.charset = s.scriptCharset;   
  •         //如果datatype不是jsonp,但是url卻是跨域的。采用scriptr的   
  •         //onload或onreadystatechange事件來觸發(fā)回調(diào)函數(shù)。   
  •        if (!jsonp) {   
  •             var done = false;   
  •             // 對所有瀏覽器都加上處理器   
  •             script.onload = script.onreadystatechange = function() {   
  •             if (!done&& (!this.readyState || this.readyState == "loaded"    
  • || this.readyState == "complete")) {   
  •                     done = true;    success();   
  •                     complete();head.removeChild(script);   
  •                 }   
  •         };   
  •     }   
  •     head.appendChild(script);   
  • // 已經(jīng)使用了script 元素注射來處理所有的事情   
  •     return undefined;   
  • }   
  • var requestDone = false;   
  • // 創(chuàng)建request,IE7不能通過XMLHttpRequest來完成,只能通過ActiveXObject   
  • var xhr = window.ActiveXObject                               ⑥   
  •          new ActiveXObject("Microsoft.XMLHTTP"): new XMLHttpRequest();   
  • // 創(chuàng)建一個請求的連接,在opera中如果用戶名為null會彈出login窗口中。   
  • if (s.username)xhr.open(type, s.url, s.async, s.username, s.password);   
  • else    xhr.open(type, s.url, s.async);   
  • // try/catch是為防止FF3在跨域請求時報錯   
  • try {// 設(shè)定Content-Type                                              ⑦   
  •     if (s.data)   
  •         xhr.setRequestHeader("Content-Type", s.contentType);   
  •         // 設(shè)定If-Modified-Since   
  •     if (s.ifModified)   
  •         xhr.setRequestHeader("If-Modified-Since",   
  •             jQuery.lastModified[s.url]|| "Thu, 01 Jan 1970 00:00:00 GMT");   
  • // 這里是為了讓服務(wù)器能判斷這個請求是XMLHttpRequest   
  •     xhr.setRequestHeader("X-Requested-With""XMLHttpRequest");   
  • // 設(shè)定 Accepts header 。指能接收的content-type,在服務(wù)器端設(shè)定   
  •     xhr.setRequestHeader("Accept", s.dataType && s.accepts[s.dataType]   
  •              s.accepts[s.dataType] + ", */*": s.accepts._default);   
  • catch (e) {}   
  • //攔截方法,我們可以在send之前進行攔截。返回false就不send   
  • if (s.beforeSend && s.beforeSend(xhr, s) === false) {         ⑧   
  •     // 清除active 請求計數(shù)   
  •     s.global && jQuery.active--;   
  •     xhr.abort();   
  •     return false;   
  • }   
  •   
  • // 觸發(fā)全局的ajaxSend事件   
  • if (s.global)   jQuery.event.trigger("ajaxSend", [xhr, s]);   
  • // 等待response返回,主要是為后面setInterval用。   
  • var onreadystatechange = function(isTimeout) {           ⑨   
  • // 接收成功或請求超時   
  • if (!requestDone && xhr&& (xhr.readyState == 4 ||isTimeout == "timeout")) { requestDone = true;   
  •          //清除定時器   
  •         if (ival) {clearInterval(ival);     ival = null;    }   
  •     // 分析status:tiemout-->error-->notmodified-->success   
  •     status = isTimeout == "timeout"  "timeout" : !jQuery   
  •         ttpSuccess(xhr) ? "error" : s.ifModified&& jQuery.   
  • httpNotModified(xhr, s.url) ? "notmodified""success";   
  •         //如果success且返回了數(shù)據(jù),那么分析這些數(shù)據(jù)   
  •     if (status == "success") {                     
  •         try {   data = jQuery.httpData(xhr, s.dataType, s);   
  •              } catch (e) {  status = "parsererror"; }   
  •     }   
  • // 分析數(shù)據(jù)成功之后,進行l(wèi)ast-modified和success的處理。                
  •     if (status == "success") {   
  •         var modRes;   
  •           try {modRes = xhr.getResponseHeader("Last-Modified");   
  •             } catch (e) {   //FF中如果head取不到,會拋出異常}    
  •          //保存last-mordified的標識。   
  •         if (s.ifModified && modRes)jQuery.lastModified[s.url] = modRes;   
  •        // JSONP 有自己的callback   
  •         if (!jsonp) success();   
  •     } else  // 失敗時的處理   
  •     jQuery.handleError(s, xhr, status);   
  • // 無論如何都進行cpmplate.timeout和接收成功   
  •     complete();   
  • if (s.async)    xhr = null// 防內(nèi)存泄漏   
  • }   
  • };   
  • if (s.async) {   
  • // 這里是采用poll的方式,不是push的方式   
  • //這里為什么不采用onreadystatechange?   
  • var ival = setInterval(onreadystatechange, 13);   
  • //如果過了timeout還沒有請求到,會中斷請求的。   
  •     if (s.timeout > 0)   
  •         setTimeout(function() {                    
  •             if (xhr) {  xhr.abort();   
  •                 if (!requestDone)   onreadystatechange("timeout");  }   
  •         }, s.timeout);   
  •     }   
  • // 發(fā)送   
  • try {xhr.send(s.data); catch(e){jQuery.handleError(s,xhr,null,e);} ⑩   
  • // firefox 1.5 doesn't fire statechange for sync requests   
  • if (!s.async)   onreadystatechange();   
  • function success() {   
  •     // 調(diào)用構(gòu)建請求對象時指定的success回調(diào)。   
  •     if (s.success)  s.success(data, status);   
  •     // 執(zhí)行全局的回調(diào)   
  •     if (s.global)   jQuery.event.trigger("ajaxSuccess", [xhr, s]);   
  •     }   
  • function complete() {   
  •     // 本地的回調(diào)   
  •     if (s.complete) s.complete(xhr, status);   
  •     // 執(zhí)行全局的回調(diào)   
  •     if (s.global)   jQuery.event.trigger("ajaxComplete", [xhr, s]);   
  •     // 全局的ajax計數(shù)器   
  •     if (s.global && !--jQuery.active)jQuery.event.trigger("ajaxStop");   
  •     }   
  • // return XMLHttpRequest便進行about()或其它操作.   
  • return xhr;   
  • },   
  • Jquery.ajax是大包大攬的非常復(fù)雜的一個方法。它并沒有像其它的lib一樣,把每個小部分都分開來。它是整個都整在一個函數(shù)中。看起來很多,實際上上也沒有脫離前面所說的ajax的請求的五步。它的很大一部分代碼在處理跨域請求的處理上。下面就分別就ajax的代碼進行分析。   
  • ajaxSettings   
  • 在①處通過繼承的方式把傳入?yún)?shù)s和默認的jQuery.ajaxSettings都clone到s變量中。S的同名屬性會覆蓋jQuery.ajaxSettings的同名屬性。這里兩次繼承s,以便在測試中能檢測。   
  • //默認的ajax的請求參數(shù)   
  •     ajaxSettings : {   
  •         url : location.href,//默認是地址欄中url   
  •         global : true,//默認支持全局的ajax事件   
  •         type : "GET",   
  •         timeout : 0,   
  •         contentType : "application/x-www-form-urlencoded",     
  •      processData : true,   
  •         async : true,   
  •         data : null,   
  •         username : null,   
  •         password : null,   
  •         accepts : {   
  •             xml : "application/xml, text/xml",   
  •             html : "text/html",   
  •             script : "text/javascript, application/javascript",   
  •             json : "application/json, text/javascript",   
  •             text : "text/plain",   
  •             _default : "*/*"  
  •         }   
  • 這是默認的ajax的設(shè)定,我們要在參數(shù)s設(shè)定同名的屬性來覆蓋這些屬性。但是我們不能覆蓋accepts。這個會在后面的代碼用到。我們可以通過設(shè)定s.dataType等于accepts中的某一個屬性key指定請求的data類型,如xml,html,script,json,text。dataType還支持默認的_default和跨域的jsonp。不過其最終會解析成script。   
  • scriptTag   
  • ②~⑥是處理跨域請求的部分。對于dataType為jsonp的類型,給其請求的字符串(可能是s.data)加上callback=callbackfn的key/value串,然后在window下注冊一個callbackfn的函數(shù)。這個函數(shù)的形式如callbackfn(data){ data = tmp;success();complete();}。它代理了通過ajax(s)的傳入s參數(shù)中success();complete()的功能。它就是調(diào)用這個函數(shù),實際上是調(diào)用success();complete()的函數(shù)。   
  • 那么怎么調(diào)用呢?ajax不支持跨域。在⑤處,我們可以看到這里是采用scriptTag的方式來完成。先在頁面的<head>中添加一個<script src=url />的標簽。因為在<head>中。瀏覽器會自動載入并運行請求返回的script。如果是jsonp的形式,服務(wù)器端還要動態(tài)生成的content-type為script的代碼:callbackfn(data);只有這樣才會調(diào)用在window中注冊的函數(shù)callbackfn。同時傳入所需要的參數(shù)。   
  • 如dataType == "script"形式的跨域,那只能是通過script.onload 或 script.onreadystatechange事件來觸發(fā)回調(diào)。這里我們可以通過服務(wù)器返回的script代碼:var data=xxx。來傳遞參數(shù)給s.success();s.complete()。Jquery這里采用是全局變量data來進行操作的。   
  • Ajax Event   
  • ④是采用了jQuery.event.trigger("ajaxStart");來觸發(fā)全局的ajaxStart事件。這也是說只要注冊了這個事件的元素,在任何的ajax的請求時ajaxStart都會執(zhí)行元素注冊的事件處理函數(shù)。這和Ext的事件有點相似。但是它不是全局的。   
  • jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i, o) {   
  •     jQuery.fn[o] = function(f) {// f:function   
  •         return this.bind(o, f);   
  •     };   
  • 上面的代碼是為jquery對象注冊了ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend這幾種ajax的事件方法,在jquery.ajax中不同的時刻都會觸發(fā)這些事件。當然我們也可以采用s.global=false來設(shè)定不觸發(fā)這些事件。   
  • 因為這是全局的,個人認為其設(shè)計的目的就是為了在這些時候能以某種形式來告訴用戶ajax的進行的狀態(tài)。如在ajaxstart的時候,我們可能通過一個topest的div層(加上遮罩的效果)的元素注冊一個ajaxstart事件的處理方法。該方法就是顯示這個層和顯示“你的數(shù)據(jù)正在提交。。?!边@個的提示。這是這6種事件的最佳用法了。   
  • 如果進行私有處理,那么要在事件的處理函數(shù)中進行判斷。因為每個事件處理函數(shù)的第二參數(shù)是jquery.ajax(s)的s參數(shù)。我們可以在這個參數(shù)中做私有的標識,如eventType:xxx。每類不同的請求有不同的eventType值。在事件處理函數(shù)再根據(jù)這個eventType==xxx進行判斷,從而進行私有的處理。如果有大量的這樣的私有處理也是會影響ajax的效率的。   
  • setRequestHeader   
  • ⑥處是創(chuàng)建一個xhr對象并通過open來創(chuàng)建一個連接(socket)。   
  • ⑦處是設(shè)定請求的頭部(setRequestHeader)。如果data的存在的話,那就得設(shè)定Content-Type,便于服務(wù)器按一定的規(guī)則來解碼。可以看出post的方式通過data傳遞數(shù)據(jù)要安全一點。   
  • 那么服務(wù)器如果區(qū)別這個請求是ajax呢?因為同步和異步ajax的請求的頭文件是一樣的。我們?nèi)绻ㄟ^X-Requested-With"="XMLHttpRequest”來標識這個請求是ajax的請求。如果服務(wù)器硬是要區(qū)分的話,就可以通過獲取該頭部來判斷。   
  • 在頭部的定義中,還可能通過Accept來指定接受的數(shù)據(jù)的類型,如application/xml, text/xml", "text/html", "text/javascript, 等等。   
  • 頭部還有一個If-Modified-Since的屬性用來提高效率的。它和”Last-Modified配合起來使用。在瀏覽器第一次請求某一個URL時,服務(wù)器端的返回狀態(tài)會是200,內(nèi)容是你請求的資源,同時有一個Last-Modified的屬性標記此文件在服務(wù)期端最后被修改的時間,格式類似這樣:Last-Modified: Fri, 12 May 2006 18:53:33 GMT    
  • 客戶端第二次請求此URL時,根據(jù) HTTP 協(xié)議的規(guī)定,瀏覽器會向服務(wù)器傳送 If-Modified-Since 報頭,詢問該時間之后文件是否有被修改過:  If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT    如果服務(wù)器端的資源沒有變化,則自動返回 HTTP 304 (Not Changed.)狀態(tài)碼,內(nèi)容為空,這樣就節(jié)省了傳輸數(shù)據(jù)量。   
  • 當服務(wù)器端代碼發(fā)生改變或者重啟服務(wù)器時,則重新發(fā)出資源,返回和第一次請求時類似。從而保證不向客戶端重復(fù)發(fā)出資源,也保證當服務(wù)器有變化時,客戶端能夠得到最新的資源。   
  • 攔截處理   
  • ⑧處是一個send之前的攔截處理,可以通過s. beforeSend(xhr, s)函數(shù)的形式傳入攔截函數(shù)。保證在發(fā)送之前確保滿足某些條件。在取得返回數(shù)據(jù)的時候,也可以通過s.dataFilter(data, type);形式來攔截處理data。不過這里主要的作用對data進一步的篩選。   
  • onreadystatechange   
  • ⑨處是onreadystatechange的回調(diào)處理。這里采用是poll的形式進行處理。它把返回的狀態(tài)分成status:tiemout-->error-->notmodified-->success—>parsererror這幾種。如果status == "success"那么分析這些數(shù)據(jù)之后再進行l(wèi)ast-modified相關(guān)的處理。為了不取回沒有修改過數(shù)據(jù)。   
  • 分析數(shù)據(jù)的代碼如下:   
  • //處理請求返回的數(shù)據(jù)   
  •     httpData : function(xhr, type, s) {   
  •         var ct = xhr.getResponseHeader("content-type"),    
  •           xml = type == "xml"   || !type && ct && ct.indexOf("xml") >= 0,    
  •            data = xml? xhr.responseXML  : xhr.responseText;   
  •         if (xml && data.documentElement.tagName == "parsererror")   
  •             throw "parsererror";   
  •         //允許一個pre-filtering函數(shù)清潔repsonse        
  •         if (s && s.dataFilter)   
  •             data = s.dataFilter(data, type);   
  •                 //script時,就運行   
  •         if (type == "script")   jQuery.globalEval(data);   
  •         //json,生成json對象。   
  •         if (type == "json")     data = eval("(" + data + ")");   
  •         return data;   
  •     },   
  • 如果返回的content-type是xml,html,text等都返回。對script執(zhí)行jQuery.globalEval來執(zhí)行它。對于Json類型,通過eval來生成返回的json對象。   
  • // 在全局的范圍eval 代碼,也就是在<head></head>中   
  • globalEval : function(data) {   
  •     data = jQuery.trim(data);   
  •         if (data) {   
  • // Inspired by code by Andrea Giammarchi   
  • // http://webreflection.blogspot.com/2007/08/   
  • //global-scope-evaluation-and-dom.html   
  •     var head = document.getElementsByTagName("head")[0]   
  •                         || document.documentElement,   
  •         script = document.createElement("script");   
  •     script.type = "text/javascript";   
  •     if (jQuery.browser.msie)    script.text = data;   
  •     else    script.appendChild(document.createTextNode(data));   
  •   
  •     // Use insertBefore instead of appendChild to circumvent an IE6   
  •     // bug. This arises when a base node is used (#2709).   
  •         head.insertBefore(script, head.firstChild);   
  •         head.removeChild(script);   
  •             }       },   
  •                   
  • 本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
    打開APP,閱讀全文并永久保存 查看更多類似文章
    猜你喜歡
    類似文章
    jQuery之a(chǎn)jax實現(xiàn)篇
    $.ajax,axios,fetch三種ajax請求的區(qū)別
    觸碰jQuery:AJAX異步詳解(跨域請求的一種實現(xiàn))
    jquery對ajax的支持
    Ajax 操作
    jQuery基礎(chǔ)教程筆記 45(下)
    更多類似文章 >>
    生活服務(wù)
    熱點新聞
    分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
    綁定賬號成功
    后續(xù)可登錄賬號暢享VIP特權(quán)!
    如果VIP功能使用有故障,
    可點擊這里聯(lián)系客服!

    聯(lián)系客服