百度的一个Ajax跨域方法

JavaScript是没有域的限制
服务器君一共花费了301.295 ms进行了5次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

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这段脚本中还有一些小的技巧也值得我们学习。

本文地址:http://www.nowamagic.net/librarys/veda/detail/615,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/615

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《深入理解计算机系统(原书第2版)》 布莱恩特(Randal E.Bryant) (作者), 奥哈拉伦(David R.O'Hallaron) (作者), 龚奕利 (译者), 雷迎春 (译者)

《深入理解计算机系统》从程序员的视角详细阐述计算机系统的本质概念,并展示这些概念如何实实在在地影响应用程序的正确性、性能和实用性。全书共12章,主要内容包括信息的表示和处理、程序的机器级表示、处理器体系结构、优化程序性能、存储器层次结构、链接、异常控制流、虚拟存储器、系统级I/O、网络编程、并发编程等。书中提供子大量的例子和练习题,并给出部分答案,有助于读者加深对正文所述概念和知识的理解。

更多计算机宝库...