Kris Zyp 씨가 미래를 대비한 100줄짜리 Ajax wrapper를 만들었습니다:

IE8의 새로운 기능인 XDocmainRequest는, 크로스 사이트 요청을 위해 추가된 새로운 API로서, W3C의 크로스-사이트 접근 제안 대신 사용할 수 있습니다. 그냥 재미삼아, 다음 세대 웹 개발자들을 위해 고전적인 Ajax request wrapper 함수는 어떻게 보일런지 보여주고자 했다. 그냥 XMLHttpRequest를 몇번 호출하는 것이 너무 쉬우니까 우리는 대신 이렇게 했다:

[code:JScript]
function doRequest(method,url,async,onLoad,onProgress) {
    var xhr;
    if ((onProgress || isXDomainUrl(url)) && window.XDomainRequest) {
        // if it is x-domain or streaming/incremental updates are needed we will use IE's XDomainRequest for IE
        // streaming/interactive mode is broken in IE's XHR, but for some reason works in XDR (with onprogress), so we will
        // need to use XDR if incremental updates are necessary
        // see bug https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=334813
         if (url.match(/^https:/) && !onProgress) {
            // XDR doesn’t work for secure https communication
            // see bug https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=333380
            loadUsingScriptTag(url); // script tag insertion can be more secure than XDR
                // in some situations because it supports https
            return;
    }
        xhr = new XDomainRequest;
        // relative paths don’t work in XDomainRequest, see bug https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=333275
    if (!url.match(/^http:/)) { // test to see if it is an absolute url
            url = absoluteUrl(location.href,url); // must have a function to turn it into an absolute url
    }
    if (!(method == “GET” || method == “POST”)) {
        // XDomainRequest does not support methods besides GET and POST
        // see bug https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=334809
        // We will try to add the method as a parameter and hope the server will understand… good luck :/
        url += “&method=” + method;
        method = “POST”;
    }
    function xdrLoad() {
       if (xhr.contentType.match(/\/xml/)){
        // there is no responseXML in XDomainRequest, so we have to create it manually
        var dom = new ActiveXObject(”Microsoft.XMLDOM”);
        dom.async = false;
        dom.loadXML(xhr.responseText,200);
        onLoad(dom);
       }
       else {
           onLoad(xhr.responseText,200); // we will assume that the status code is 200, XDomainRequest rejects all other successful status codes
        // see bug https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=334804
       }
    }
    if (async === false) {
        // XDomainRequest does not support synchronous requests
        // see bug https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=336031
        // so we will try to block execution on our own (which is not really possible in any reasonable manner)
        var loaded;
        xhr.onload = function() {
        loaded = true;
        xdrLoad();
        }
            xhr.open(method,url);
        xhr.send(null);
        while(!loaded) { // try to block until the response is received
        // I am sure the user won’t mind just clicking OK so we can block execution
        alert(”Waiting for the response, please click OK because it probably is here now”);
        }
         return;
    }
    else {    // do an asynchronous request with XDomainRequest
            xhr.onload = xdrLoad;
            xhr.open(method,url);
            xhr.onprogress = onProgress;
    }
    }
    // we will mercifully skip all the branches for ActiveXObject(”Microsoft.XMLHTTP”) to accomodate IE6 and lower
    else {
        xhr = new XMLHttpRequest; // use the standard XHR for same origin and browsers that implement cross-site
            // W3C requests and streaming
        xhr.open(method,url,async);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 3) // interactive mode
                onProgress(xhr.responseText);
            if (xhr.readyState == 4) // finished
                onLoad(xhr.responseText,xhr.status);
        }
    }
    xhr.send(null); // finally send the request whether it be XDR or XHR

    // and supporting functions
    function absoluteUrl : function(baseUrl, relativeUrl) {
        // This takes a base url and a relative url and resolves the target url.
        // For example:
        // resolveUrl(”http://www.domain.com/path1/path2″,”../path3″) ->”http://www.domain.com/path1/path3″
        //
        if (relativeUrl.match(/\w+:\/\//))
            return relativeUrl;
        if (relativeUrl.charAt(0)==’/') {
            baseUrl = baseUrl.match(/.*\/\/[^\/]+/)
            return (baseUrl ? baseUrl[0] : ”) + relativeUrl;
        }
            //TODO: handle protocol relative urls:  ://www.domain.com
        baseUrl = baseUrl.substring(0,baseUrl.length - baseUrl.match(/[^\/]*$/)[0].length);// clean off the trailing path
        if (relativeUrl == ‘.’)
            return baseUrl;
        while (relativeUrl.substring(0,3) == ‘../’) {
            baseUrl = baseUrl.substring(0,baseUrl.length - baseUrl.match(/[^\/]*\/$/)[0].length);
            relativeUrl = relativeUrl.substring(3);
        }
        return baseUrl + relativeUrl;
    }
    function loadUsingScriptTag(url) {
        … do JSONP here if we want
    }

}
음... IE팀은 제발 표준을 좀 지켜줬으면!

from 100Line Ajax Wrapper on Ajaxian
Posted by 행복한고니 트랙백 0 : 댓글 0