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
댓글을 달아 주세요