前回からの今回までの間にjQuery 1.
大きな変更点としては、
ところで、
jQuery.ajax()
jQuery.
2530: // Last-Modified header cache for next request
2531: lastModified: {},
2532:
2533: ajax: function( s ) {
2534: var jsonp, jsre = /=\?(&|$)/g, status, data;
2535:
2536: // Extend the settings, but re-extend 's' so that it can be
2537: // checked again later (in the test suite, specifically)
2538: s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
2539:
2540: // convert data if not already a string
2541: if ( s.data && s.processData && typeof s.data != "string" )
2542: s.data = jQuery.param(s.data);
2543:
2531行目では、
そして、
2544: // Handle JSONP Parameter Callbacks
2545: if ( s.dataType == "jsonp" ) {
2546: if ( s.type.toLowerCase() == "get" ) {
2547: if ( !s.url.match(jsre) )
2548: s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
2549: } else if ( !s.data || !s.data.match(jsre) )
2550: s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
2551: s.dataType = "json";
2552: }
2553:
2554: // Build temporary JSONP function
2555: if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
2556: jsonp = "jsonp" + jsc++;
2557:
2558: // Replace the =? sequence both in the query string and the data
2559: if ( s.data )
2560: s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
2561: s.url = s.url.replace(jsre, "=" + jsonp + "$1");
2562:
2563: // We need to make sure
2564: // that a JSONP style response is executed properly
2565: s.dataType = "script";
2566:
2567: // Handle JSONP-style loading
2568: window[ jsonp ] = function(tmp){
2569: data = tmp;
2570: success();
2571: complete();
2572: // Garbage collect
2573: window[ jsonp ] = undefined;
2574: try{ delete window[ jsonp ]; } catch(e){}
2575: if ( head )
2576: head.removeChild( script );
2577: };
2578: }
2579:
2545~2552行目でJSONP形式でデータを受け取るための前処理を行います。リクエストメソッドがGETで、
2555~2578行目は、
2568行目でwindowオブジェクトにコールバック関数を先ほど生成した名前で登録します。関数の処理内容としては、
2580: if ( s.dataType == "script" && s.cache == null )
2581: s.cache = false;
2582:
2583: if ( s.cache === false && s.type.toLowerCase() == "get" ) {
2584: var ts = (new Date()).getTime();
2585: // try replacing _= if it is there
2586: var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
2587: // if nothing was replaced, add timestamp to the end
2588: s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
2589: }
2590:
2580行目からは、
また、
2591: // If data is available, append data to url for get requests
2592: if ( s.data && s.type.toLowerCase() == "get" ) {
2593: s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
2594:
2595: // IE likes to send both get and post data, prevent this
2596: s.data = null;
2597: }
2598:
2592行目からは、
2599: // Watch for a new set of requests
2600: if ( s.global && ! jQuery.active++ )
2601: jQuery.event.trigger( "ajaxStart" );
2602:
2601行目は、
2603: // If we're requesting a remote document
2604: // and trying to load JSON or Script with a GET
2605: if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && ( s.dataType == "script" || s.dataType =="json" ) && s.type.toLowerCase() == "get" ) {
2606: var head = document.getElementsByTagName("head")[0];
2607: var script = document.createElement("script");
2608: script.src = s.url;
2609: if (s.scriptCharset)
2610: script.charset = s.scriptCharset;
2611:
2612: // Handle Script loading
2613: if ( !jsonp ) {
2614: var done = false;
2615:
2616: // Attach handlers for all browsers
2617: script.onload = script.onreadystatechange = function(){
2618: if ( !done && (!this.readyState ||
2619: this.readyState == "loaded" || this.readyState == "complete") ) {
2620: done = true;
2621: success();
2622: complete();
2623: head.removeChild( script );
2624: }
2625: };
2626: }
2627:
2628: head.appendChild(script);
2629:
2630: // We handle everything using the script element injection
2631: return undefined;
2632: }
2633:
2605行目からは、
2628行目で作成したscriptタグを実際に追加します。
2634: var requestDone = false;
2635:
2636: // Create the request object; Microsoft failed to properly
2637: // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2638: var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
2639:
2640: // Open the socket
2641: xml.open(s.type, s.url, s.async, s.username, s.password);
2642:
2634行目のrequestDoneはリクエストを送信済みかどうかのフラグで、
2643: // Need an extra try/catch for cross domain requests in Firefox 3
2644: try {
2645: // Set the correct header, if data is being sent
2646: if ( s.data )
2647: xml.setRequestHeader("Content-Type", s.contentType);
2648:
2649: // Set the If-Modified-Since header, if ifModified mode.
2650: if ( s.ifModified )
2651: xml.setRequestHeader("If-Modified-Since",
2652: jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
2653:
2654: // Set header so the called script knows that it's an XMLHttpRequest
2655: xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
2656:
2657: // Set the Accepts header for the server, depending on the dataType
2658: xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
2659: s.accepts[ s.dataType ] + ", */*" :
2660: s.accepts._default );
2661: } catch(e){}
2662:
2644行目からは、
2647行目は、
2651:行目は、
2655行目は、
2658行目は、
2663: // Allow custom headers/mimetypes
2664: if ( s.beforeSend )
2665: s.beforeSend(xml);
2666:
2667: if ( s.global )
2668: jQuery.event.trigger("ajaxSend", [xml, s]);
2669:
もし、
そして、
2670: // Wait for a response to come back
2671: var onreadystatechange = function(isTimeout){
2672: // The transfer is complete and the data is available, or the request timed out
2673: if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
2674: requestDone = true;
2675:
2676: // clear poll interval
2677: if (ival) {
2678: clearInterval(ival);
2679: ival = null;
2680: }
2681:
2682: status = isTimeout == "timeout" && "timeout" ||
2683: !jQuery.httpSuccess( xml ) && "error" ||
2684: s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
2685: "success";
2686:
2687: if ( status == "success" ) {
2688: // Watch for, and catch, XML document parse errors
2689: try {
2690: // process the data (runs the xml through httpData regardless of callback)
2691: data = jQuery.httpData( xml, s.dataType );
2692: } catch(e) {
2693: status = "parsererror";
2694: }
2695: }
2696:
2697: // Make sure that the request was successful or notmodified
2698: if ( status == "success" ) {
2699: // Cache Last-Modified header, if ifModified mode.
2700: var modRes;
2701: try {
2702: modRes = xml.getResponseHeader("Last-Modified");
2703: } catch(e) {} // swallow exception thrown by FF if header is not available
2704:
2705: if ( s.ifModified && modRes )
2706: jQuery.lastModified[s.url] = modRes;
2707:
2708: // JSONP handles its own success callback
2709: if ( !jsonp )
2710: success();
2711: } else
2712: jQuery.handleError(s, xml, status);
2713:
2714: // Fire the complete handlers
2715: complete();
2716:
2717: // Stop memory leaks
2718: if ( s.async )
2719: xml = null;
2720: }
2721: };
2722:
2670~2721行目は、
2674行目は、
2677行目は、
2682~2685行目は、
2687~2695行目は、
2697行目からは、
2710行目は、
2712行目は、
2715行目は、
最後に非同期呼び出しの場合にメモリリークを避けるために、
2723: if ( s.async ) {
2724: // don't attach the handler to the request, just poll it instead
2725: var ival = setInterval(onreadystatechange, 13);
2726:
2727: // Timeout checker
2728: if ( s.timeout > 0 )
2729: setTimeout(function(){
2730: // Check to see if the request is still happening
2731: if ( xml ) {
2732: // Cancel the request
2733: xml.abort();
2734:
2735: if( !requestDone )
2736: onreadystatechange( "timeout" );
2737: }
2738: }, s.timeout);
2739: }
2740:
2723~2739行目は、
次に2728行目でタイムアウト時間
2741: // Send the data
2742: try {
2743: xml.send(s.data);
2744: } catch(e) {
2745: jQuery.handleError(s, xml, null, e);
2746: }
2747:
2748: // firefox 1.5 doesn't fire statechange for sync requests
2749: if ( !s.async )
2750: onreadystatechange();
2751:
2752: function success(){
2753: // If a local callback was specified, fire it and pass it the data
2754: if ( s.success )
2755: s.success( data, status );
2756:
2757: // Fire the global callback
2758: if ( s.global )
2759: jQuery.event.trigger( "ajaxSuccess", [xml, s] );
2760: }
2761:
2743行目で実際にリクエストを送信します。もし、
2750行目では、
2752行目からは、
2762: function complete(){
2763: // Process result
2764: if ( s.complete )
2765: s.complete(xml, status);
2766:
2767: // The request was completed
2768: if ( s.global )
2769: jQuery.event.trigger( "ajaxComplete", [xml, s] );
2770:
2771: // Handle the global AJAX counter
2772: if ( s.global && ! --jQuery.active )
2773: jQuery.event.trigger( "ajaxStop" );
2774: }
2775:
2776: // return XMLHttpRequest to allow aborting the request etc.
2777: return xml;
2778: },
2779:
2762~2778行目は、
また、
最後に2777行目で、
jQuery.handleError()
2780: handleError: function( s, xml, status, e ) {
2781: // If a local callback was specified, fire it
2782: if ( s.error ) s.error( xml, status, e );
2783:
2784: // Fire the global callback
2785: if ( s.global )
2786: jQuery.event.trigger( "ajaxError", [xml, s, e] );
2787: },
2788:
2780行目からは、
jQuery.httpSuccess()
2789: // Counter for holding the number of active queries
2790: active: 0,
2791:
2792: // Determines if an XMLHttpRequest was successful or not
2793: httpSuccess: function( r ) {
2794: try {
2795: // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
2796: return !r.status && location.protocol == "file:" ||
2797: ( r.status >= 200 && r.status 2798: jQuery.browser.safari && r.status == undefined;
2799: } catch(e){}
2800: return false;
2801: },
2802:
2790行目のactiveは、
2793行目からは、
jQuery.httpNotModified()
2803: // Determines if an XMLHttpRequest returns NotModified
2804: httpNotModified: function( xml, url ) {
2805: try {
2806: var xmlRes = xml.getResponseHeader("Last-Modified");
2807:
2808: // Firefox always returns 200. check Last-Modified date
2809: return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
2810: jQuery.browser.safari && xml.status == undefined;
2811: } catch(e){}
2812: return false;
2813: },
2814:
2804行目からは、
jQuery.httpData()
2815: httpData: function( r, type ) {
2816: var ct = r.getResponseHeader("content-type");
2817: var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
2818: var data = xml ? r.responseXML : r.responseText;
2819:
2820: if ( xml && data.documentElement.tagName == "parsererror" )
2821: throw "parsererror";
2822:
2823: // If the type is "script", eval it in global context
2824: if ( type == "script" )
2825: jQuery.globalEval( data );
2826:
2827: // Get the JavaScript object, if JSON is used.
2828: if ( type == "json" )
2829: data = eval("(" + data + ")");
2830:
2831: return data;
2832: },
2833:
2815行目からのjQuery.
2820行目は、
2825行目は、
2829行目は、
最後に2831行目で、