看看baidu是如何AJAX跨域的

5iasp
领域专家: 后端开发技术领域
2008-12-24 09:32:27
看看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跨域的时候花儿也谢了
...全文
22519 243 打赏 收藏 转发到动态 举报
写回复
用AI写文章
243 条回复
切换为时间正序
请发表友善的回复…
发表回复
wumingmao1990 2012-08-17
  • 打赏
  • 举报
回复
没看懂。。
似梦飞花 2012-06-26
  • 打赏
  • 举报
回复
留个爪印
david522 2012-05-16
  • 打赏
  • 举报
回复
学习了
hzhtc_555 2012-02-23
  • 打赏
  • 举报
回复
学习了,感谢高手的教程,谢谢!
鸭不梨儿 2012-02-23
  • 打赏
  • 举报
回复
标记,以后慢慢看。
asd5640252 2011-12-21
  • 打赏
  • 举报
回复
mark
ym231074255 2011-12-01
  • 打赏
  • 举报
回复
看不懂。。MARK
tylrr123 2011-07-24
  • 打赏
  • 举报
回复
收藏了 谢谢
OPPPPOP 2011-07-04
  • 打赏
  • 举报
回复
那我觉得用script 标签 来代替Ajax非常好 都是script的事 多好的 非要扯过来个 xmlHttprequest 返回值还要 script来解析 麻烦
wujj_wtj 2011-07-04
  • 打赏
  • 举报
回复
学习了
lucifer 2011-05-12
  • 打赏
  • 举报
回复
mark一下
鱼呗 2010-12-17
  • 打赏
  • 举报
回复
Mark
andyniuandyniu 2010-12-12
  • 打赏
  • 举报
回复
学习mark
baimin5211314 2010-12-08
  • 打赏
  • 举报
回复
膜拜,楼主中......
edgesun 2010-11-27
  • 打赏
  • 举报
回复
大家都知道ajax不能跨域,还在拼命的找跨域方法,俺也是来取经的。学习了
myqq155120699 2010-11-27
  • 打赏
  • 举报
回复
mark

以后再看。
itaoo 2010-10-05
  • 打赏
  • 举报
回复
mark
jblxmn 2010-09-28
  • 打赏
  • 举报
回复
挖份 MARK下
cph1737 2010-09-26
  • 打赏
  • 举报
回复
学习了,非常感谢
黄瓜 2010-09-26
  • 打赏
  • 举报
回复

竟然没看懂~~
加载更多回复(223)

87,989

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧