您的位置:首页 > 大数据 > 人工智能

看看baidu是如何AJAX跨域的

2013-12-20 17:27 375 查看

看看baidu是如何AJAX跨域的

最近做个人网站遇到AJAX跨子域名的问题。

偶尔看到baidu的通行证处理都是在二级域名passport.baidu.com中处理的,

但是baidu很多地方登录都好像是用ajax处理的,他是怎么做的呢?研究了一下,发现一个小技巧。

不防让大家也借鉴一下。

在http://zhidao.baidu.com/ 未登录用户回答问题时会用iframe调用http://zhidao.baidu.com/userlogin.html

userlogin.html有下面的javascript


<SCRIPT LANGUAGE="JavaScript">


document.domain="baidu.com";


<!--


function G(id){if(typeof(id)=="string"){return document.getElementById(id);}return id;}


function showInfo(obj){


    if(obj.checked == true){


        G("memInfo").style.display="block";


    }else{


        G("memInfo").style.display="none";


    }


}


function request(id,url){


     oScript = document.getElementById(id);


     var head = document.getElementsByTagName("head").item(0);


     if (oScript) {


        head.removeChild(oScript);


     }


     oScript = document.createElement("script");


     oScript.setAttribute("src", url);


     oScript.setAttribute("id",id);


     oScript.setAttribute("type","text/javascript");


     oScript.setAttribute("language","javascript");


     head.appendChild(oScript);


     return oScript;


}


var loginTimer=null;


var loginState=-1;


var tryTime=0;


function PSP_ik(isOk){


    if(isOk==0){


        G("errorInfo").style.display="none";


        loginState=1;


        if(parent.loginSuccess){


            parent.Pop.hide();


            parent.loginSuccess();


        }


    }


    else


    {


        loginFalse();


    }


}




function loginFalse(){


    loginState=0;


    var err=G("errorInfo");


    err.innerHTML="用户名或密码错误,请重新登录";


    err.style.display="block";


    G("username").focus();


    tryTime++;


    if(tryTime>1){


        onLoginFailed();


    }


}


function onLoginFailed(){


    if(parent.onLoginFailed){


        parent.Pop.hide();


        parent.loginFailed();


    }else{


        document.login.u.value=escape("http://zhidao.baidu.com/q"+parent.location.search);


        doucment.login.submit();


    }


        


}


function loginTimeout(){


    if(loginState==-1){


        var err=G("errorInfo");


        err.innerHTML="操作超时,请重新登录";


        err.style.display="block";


        G("username").focus();


    }


}


function userLogin(){


    var username=G('username').value;


    var password=G('password').value;


    var memPassport=G('memPassport').checked?"on":"off";


    if(username.length<=0||password.length<=0){G("username").focus();return false;}


    var url = 'https://passport.baidu.com/?logt&tpl=ik&t=0&keyname=ik&mem_pass='+memPassport+'&username='+username + '&loginpass=' +escape(password)+ '&s=' + (new Date()).getTime();


    loginState=-1;


    var login=request("loginScript",url);


    loginTimer = setTimeout(loginTimeout, 5000);




}


window.onload=function(){


    document.loginForm.username.focus();    


    document.getElementById("username").focus(); 


}


//-->


</SCRIPT>



我们可以看到request方法处理异步请求使用动态往head中添加script而不是用xmlhttp发送get请求。

妙就妙在这。我们知道调用javascript是没有域的限制的。当加载完成时一样会执行。

当然请求参数只能通过拼url的方式了。
url通过服务器处理后直接输出loginFalse()或者PSP_ik();

非常优雅的解决了跨域的问题。

这让我们想到了用iframe当ajax上传文件一样异曲同工。

如果不需要服务器反馈,google的点击计数用new img().src=...;

当然baidu这段脚本中还有一些小的技巧也值得我们学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ajax js跨域