4年前寫過一篇
《腳本綁定回調》 進行了一些有趣的嘗試,這些嘗試現(xiàn)在在一些web產品中已經應用了好幾年了。這兩年隨著海外用戶的增多,用戶情況的復雜化,我們的服務部署也開始復雜化了,有一些用戶訪問A域名失敗,訪問B域名就可能很暢順,另一些用戶則相反。而且很多時候這并不是gslb這樣的調度可以及時檢測到和快速調整的,不由得想想,能不能進行失敗重試呢?其實也很簡單把4年前的代碼改了一改,做了一個原理性的實驗:
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
var isIE = !!window.ActiveXObject;
var useFragment=false;
function loadjs(url,callback,errcallback,url2,url3){
if(isIE){
if(useFragment){
var df = document.createDocumentFragment();
df.visitCountCallBack = function(data){
s.onreadystatechange=null;
df=null;
callback(data);
}
var s = df.createElement("SCRIPT");
df.appendChild(s);
s.onreadystatechange=function (ec,cb,u2,u3){
return function(){
if(s.readyState=="loaded") {
s.onreadystatechange=null;
df=null;
if(!u2){
ec();
}else{
loadjs(u2,cb,ec,u3)
}
}
}
}(errcallback,callback,url2,url3)
s.src = url;
}else{
var i=new ActiveXObject("htmlfile");
i.open();
i.parentWindow.visitCountCallBack=function(i){
return function(d){
i.parentWindow.errcallback=null;
i=null;
callback(d);
}
}(i);
i.parentWindow.errcallback=function(ec,cb,u2,u3){
return function(){
i.parentWindow.errcallback=null;
i=null;
if(!u2){
ec();
}else{
loadjs(u2,cb,ec,u3)
}
}
}(errcallback,callback,url2,url3)
i.write("<script src=\""+url+"\"><\/script><script defer>setTimeout(\"errcallback()\",0)<\/script>")
if(i)i.close();//如果數(shù)據被cache,運行到這一行的時候有可能回調已經完成,窗口已經關閉。
}
}else{
var i = document.createElement("IFRAME");
i.style.display="none";
i.callback=function(o){
callback(o);
i.contentWindow.callback=null;
i.src="about:blank"
i.parentNode.removeChild(i);
i = null;
};
i.errcallback = function(ec,cb,u2,u3){
return function(){
if(!u2){
ec();
}else{
loadjs(u2,cb,ec,u3)
}
}
}(errcallback,callback,url2,url3);
i.src="javascript:\"<script>function visitCountCallBack(data){frameElement.callback(data)};<\/script><script src='"+url+"'><\/script><script>setTimeout('frameElement.errcallback()',0)<\/script>\"";
document.body.appendChild(i);
}
}
function init(){
var spans = document.getElementsByTagName("span");
for(var i=0;i<spans.length;i++){
var id = spans[i].id;
var url = "http://g.qzone.qq.com/fcg-bin/cgi_emotion_list.fcg?uin=a"+id;//故意制造錯誤引發(fā)重試
var url2 = "http://g.qzone.qq.com/fcg-bin/cgi_emotion_list.fcg?uin=b"+id;//故意再次制造錯誤引發(fā)重試
var url3 = "http://g.qzone.qq.com/fcg-bin/cgi_emotion_list.fcg?uin="+id;
var callback = function(id){ return function(data){
document.getElementById(id).innerHTML = data.visitcount;
}
}(id);
var errcallback = function(id){ return function(){
document.getElementById(id).innerHTML = "無法連接到服務器";
}
}(id);
loadjs(url,callback,errcallback,url2,url3);
}
}
</SCRIPT>
</HEAD>
<BODY onload="init()">
12345(非法帳號)的訪問量:<span id="12345"></span><BR>
123456 的訪問量:<span id="123456"></span><BR>
20050606 的訪問量:<span id="20050606"></span><BR>
</BODY>
</HTML>
故意在前兩次請求中制造了錯誤,嘗試到第三個url的時候才成功。